2015-02-28 6 views
8

यह सी में आम बात का उपयोग कर रहा है के लिए:मैक्रोज़ में "do {...} जबकि (0)" और "{...} ((शून्य) 0)" के बीच व्यावहारिक अंतर?

#define FOO() do { /* body */ } while (0) 

हालांकि यह ठीक है, यह भी संभव है करने के लिए:

#define FOO() { /* body */ }((void)0) 

{...}((void)0) वही लाभ के कई हैं: आप नहीं कर सकते गलती से तर्क विलय करें, और ; लाइन के अंत में आवश्यक है, इसलिए इस तरह के अजीब अभिव्यक्ति अन-ध्यान से नहीं जाते: FOO() else {...}

केवल अंतर मैंने देखा है इसका मतलब है कि आपको if-statement में ब्रेसिज़ का उपयोग करने की आवश्यकता है।

if (a) { 
    FOO(); 
} else { 
    BAR(); 
} 

अन्य तो यह मोड़, यह अच्छी तरह से काम करने के लिए, समस्याओं do/while प्रक्रिया आम तौर पर के लिए प्रयोग किया जाता है एक ही प्रकार को रोकने लगता है:

if (a) 
    FOO(); 
else 
    BAR(); 

के रूप में लिखा जाना चाहिए।

क्या 2 विधियों के बीच कोई महत्वपूर्ण अंतर है?

ने कहा अलग ढंग से, यदि आप एक कोड आधार {...}((void)0) का उपयोग कर, do{..}while(0) उपयोग पर स्विच करना व्यावहारिक कारण हैं, एक अंतर के अलावा देखने के पहले ही उल्लेख किया?

+4

'{...} (शून्य) 0' संस्करण का प्रयोग कभी भी अभ्यास में नहीं किया जाता है - मैंने इसे पहले कभी भी नहीं देखा है। यह सादा _weird_ है! और व्यर्थ।और बेकार, क्योंकि आप इसे 'do {...} जबकि (0)' विकल्प के रूप में उपयोग नहीं कर सकते हैं। '(शून्य) 0' कास्ट आपको मूल्य के कुछ भी नहीं खरीदता है - यह लाभ से रहित है। –

+6

प्रैक्टिकल फर्क # 1: लोग जानते हैं और पहचान करते हैं '{{}} (0)' variant, और दूसरा नहीं। –

+5

आपके द्वारा इंगित अंतर बहुत बड़ा है। –

उत्तर

6

व्यावहारिक अंतर बिल्कुल वही है जो आपने इंगित किया था।

do { ... } while (0) मुहावरे का अर्थ है कि मैक्रो का उपयोग संदर्भ में किया जा सकता है जिसके लिए एक कथन की आवश्यकता होती है।

आपके द्वारा सुझाई गई मुहावरा { ... } ((void)0)सबसे संदर्भों कि एक अभिव्यक्ति की आवश्यकता होती है में सुरक्षित रूप से इस्तेमाल किया जा सकता है - लेकिन अगर यह एक unbraced if बयान में प्रयोग किया जाता है इसे विफल कर सकते हैं।

मुझे कोई अच्छा कारण एक अपरिचित मुहावरा है कि लगभग हमेशा काम करता है का उपयोग करने के बारे में सोच सकते, जब वहाँ एक प्रसिद्ध मुहावरा है कि हमेशा काम करता है।

+2

एक मामले में यह काम नहीं करता है - जब आप मैक्रो के भीतर 'ब्रेक' का उपयोग करना चाहते हैं, (स्वीकार्य रूप से ऐसा कुछ नहीं जो अक्सर किया जाता है)। – ideasman42

2

एक अंतर यह है कि आप #define FOO() do { /* body */ } while (0) के साथ ब्रेक का उपयोग कर सकते हैं लेकिन #define FOO() { /* body */ }(void)0 के साथ नहीं।

मान लीजिए कि आप एक समारोह के अंदर हैं, कहते हैं कि hello(), और #define FOO() do { /*some device operation */ } while (0) में कुछ कर रही है, लेकिन कुछ त्रुटि है ताकि आप नहीं रह गया है कि डिवाइस के साथ आगे बढ़ना चाहते हो गई लेकिन वहाँ समारोह hello() आप निष्पादित करने के लिए चाहते हैं, उसमें अन्य बयान कर रहे हैं चलो, चलो के लिए मान लीजिए एक और डिवाइस

तो अगर आप दूसरा कथन का उपयोग तो आप सबसे शायद जो hello() से बाहर बाहर निकल जाएगा, लेकिन यदि आप पहले बयान आप खुशी से break कर सकते हैं का उपयोग करें और किसी अन्य उपकरण के लिए एक ही समारोह hello() में कुछ आपरेशन कर लौट करेंगे।

+2

मुझे विश्वास नहीं है कि यह एक आकर्षक अंतर है। आप शरीर को कोड कर सकते हैं ताकि 'अगर (स्थिति) तोड़ने की बजाय; ... बाकी शरीर ... 'आप लिखते हैं' अगर (! हालत) {... बाकी शरीर ...} '। यह एक अनिवार्य रूप से मामूली परिवर्तन है। आप '{... यहां ...} (शून्य) 0' संस्करण के अंदर '0 ... जबकि (0)' एम्बेड भी कर सकते हैं। –

+0

एक उदाहरण पोस्ट करना :) – user1627167

+1

@ जोनाथन लेफ्लर स्थिति के बारे में कितने के बारे में? हालांकि आप हमेशा कोड कर सकते हैं लेकिन पठनीय होगा? इस तरह http://ideone.com/wfC6Ib – user1627167

संबंधित मुद्दे