2009-07-01 15 views
146

संभावित डुप्लिकेट:
What’s the use of do while(0) when we define a macro?
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?
do { … } while (0) what is it good for?सी बहु लाइन मैक्रो: कर/जबकि (0) बनाम दायरे ब्लॉक

मैं कुछ बहु लाइन सी मैक्रो देखा है जो एक डू/जबकि (0) लूप के अंदर लपेटे गए हैं:

 
#define FOO \ 
    do { \ 
    do_stuff_here \ 
    do_more_stuff \ 
    } while (0) 
 
#define FOO \ 
    { \ 
    do_stuff_here \ 
    do_more_stuff \ 
    } 
+4

डुप्लिकेट: http://stackoverflow.com/questions/923822/ और http://stackoverflow.com/questions/154136/ और http://stackoverflow.com/questions/257418/ – sth

+0

असल में एक और तरीका है चीजें सही हो जाओ। ({...}) वही काम कर सकता है जैसे {} जबकि (0)। रेफरी: http://www.bruceblinn.com/linuxinfo/DoWhile.html – Nybble

उत्तर

212

http://bytes.com/groups/c/219859-do-while-0-macro-substitutions

एंड्री Tarasevich: ६५१०४०३२१० लाभ (अगर कोई है) के रूप में एक बुनियादी ब्लॉक का उपयोग करने का विरोध किया कि जिस तरह से कोड लिखने की क्या हैं

का उपयोग कर के पूरे विचार 'कर/जबकि 'संस्करण एक मैक्रो बनाना है जो नियमित विवरण में विस्तारित होगा, न कि यौगिक बयान में। सभी संदर्भों में सामान्य कार्यों के उपयोग के साथ फ़ंक्शन-शैली मैक्रोज़ वर्दी का उपयोग करने के लिए किया गया है।

निम्नलिखित कोड स्केच

if (<condition>) 
    foo(a); 
else 
    bar(a); 

जहां 'foo' और 'बार' साधारण कार्य हैं पर विचार करें। अब कल्पना करें कि आप, ऊपर प्रकृति का एक मैक्रो के साथ समारोह 'foo' प्रतिस्थापित करना चाहते था

if (<condition>) 
    CALL_FUNCS(a); 
else 
    bar(a); 

अब अगर अपने मैक्रो दूसरा दृष्टिकोण (के अनुसार परिभाषित किया गया है सिर्फ '{' और '} ') कोड अब संकलित नहीं होगा, क्योंकि' if 'की' true ' शाखा अब एक यौगिक बयान द्वारा दर्शायी जाती है। और जब आप डालते हैं तो ';' इस यौगिक बयान के बाद, आपने पूरे 'अगर' कथन को समाप्त कर दिया, इस प्रकार 'अन्य' शाखा (इसलिए संकलन त्रुटि) को अनाथ कर दिया।

इस समस्या को ठीक करने का एक तरीका यह है कि ';' मैक्रो "आमंत्रण"

if (<condition>) 
    CALL_FUNCS(a) 
else 
    bar(a); 

के बाद यह संकलन होगा और अपेक्षा के अनुरूप काम है, लेकिन यह एक समान नहीं है। अधिक सुरुचिपूर्ण समाधान यह सुनिश्चित करने के लिए है कि मैक्रो एक नियमित कथन में विस्तारित हो, एक परिसर में नहीं। एक तरीका यह है कि प्राप्त करने के लिए के रूप में

#define CALL_FUNCS(x) \ 
do { \ 
    func1(x); \ 
    func2(x); \ 
    func3(x); \ 
} while (0) 

अब इस कोड

if (<condition>) 
    CALL_FUNCS(a); 
else 
    bar(a); 

बिना किसी समस्या के संकलन होगा इस प्रकार मैक्रो निर्धारित करने की है।

हालांकि, CALL_FUNCS की मेरी परिभाषा और आपके संदेश में पहला संस्करण के बीच छोटे लेकिन महत्वपूर्ण अंतर को ध्यान में रखें। मैंने } while (0) के बाद ; नहीं डाला। उस परिभाषा के अंत में को तुरंत 'डू/टाइम' का उपयोग करने के पूरे बिंदु को हरा देगा और बना देगा कि मैक्रो कंपाउंड-स्टेटमेंट संस्करण के बराबर काफी समकक्ष है।

मुझे नहीं पता कि आपके मूल संदेश में आपके द्वारा उद्धृत कोड के लेखक while (0) के बाद ; डालते हैं। इस रूप में दोनों प्रकार समकक्ष हैं। 'Do/while' संस्करण का उपयोग करने के पीछे पूरा विचार में मैक्रो में यह अंतिम ; शामिल नहीं है (कारणों से मैंने ऊपर समझाया)।

+35

मूल पोस्ट 'comp.lang.c' में मेरे द्वारा बनाई गई थी। 'bytes.com' स्पष्ट रूप से स्रोत के संदर्भ में 'comp.lang.c' की सामग्री को" लागू करता है "। – AnT

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