2012-02-29 11 views
13

संभव डुप्लिकेट:
Why are there sometimes meaningless do/while and if/else statements in C/C++ macros?मैक्रो परिभाषा में {} जबकि (0) का उपयोग क्यों करें?

मैं नीचे की तरह कोड से मुलाकात की:

#define ev_io_init(ev,cb,fd,events) \ 
do { \ 
    ev_init ((ev), (cb)); \ 
    ev_io_set ((ev),(fd),(events)); \ 
} while (0) 

मुझे पता है क्यों लेखक do { } while (0) यहाँ का उपयोग करना चाहते हैं। क्या इसमें कोई अंतर है?

#define ev_io_init(ev,cb,fd,events) { \ 
    ev_init ((ev), (cb)); \ 
    ev_io_set ((ev),(fd),(events)); \ 
} 

Btw: कोड libev से है, ev_local.h

उत्तर

10

एक do{}while(0) आप पाश से तोड़ने के लिए अनुमति देता है:

do{ 
    expr1; 
    foo(); 
    if (cond) 
     break; 
    expr2; 
    goo(); 
} while (0); 

यह है कि आप को छोड़कर एक सरल ब्लॉक {...} की तरह ही है जब आप break कथन के साथ चाहते हैं तो निष्पादन तोड़ सकता है। आप इसे एक साधारण कोड ब्लॉक में नहीं कर सकते, जब तक कि आपके पास एकाधिक चेक न हों, जो बोझिल हो सकता है। while(0) की स्थिति के कारण, यह अभी भी एक बार निष्पादित हो जाता है।

+8

... यह करता है, लेकिन कृपया मत ... – moonshadow

+0

यह अगर-किसी और घोंसले की संख्या कम कर देता है । – shuva

15

लूप के साथ कोड संलग्न करने से पूर्व-प्रोसेसर निर्देश के लिए कई बयानों को निष्पादित करने की अनुमति मिलती है, बिना किसी और संरचना के "तोड़ने"। निम्नलिखित पर विचार करें:

#define DO_SOMETHING() a();b();c(); 

void foo() 
{ 
    // This is ok... 
    DO_SOMETHING(); 
} 

void bar() 
{ 
    // ...whereas this would trigger an error. 
    if (condition) 
     DO_SOMETHING(); 
    else 
     blah(); 
} 

दूसरे उदाहरण टूट जाता है, तो-और कुछ-निर्माण क्योंकि तीन स्टेटमेंट एक else खंड द्वारा पीछा कर रहे हैं। इसे सही तरीके से प्रतिस्थापित करने की अनुमति देने के लिए, DO_SOMETHING में दिए गए निर्देशों को do { ... } while(0) से जोड़ा जाना चाहिए।

+3

बेशक, यदि आप इस तरह की रेखाओं को नग्न करते हैं, तो आप अपने कोड को तोड़ने के लायक हैं ... – Simon

+2

@ सिमॉन लेकिन लिनक्स कर्नेल कोडिंग शैली की सलाह नहीं है कि हम एक लाइन ब्लॉक के लिए लाइनों के अलावा नग्न का उपयोग करें? https://www.kernel.org/doc/Documentation/CodingStyle – CoderSpinoza

+2

@ कोडरस्पिनोज़ जाहिर है, और यदि मैं लिनक्स कर्नेल पर काम करना चाहता हूं तो मैं उस शैली का पालन करूंगा। कहीं और, मैं इससे बचूंगा। – Simon

23

पर विचार करें if(something) function1(); else function2();

तो function1() वास्तव में एक मैक्रो है, बस का उपयोग कर { } आप उपयोग के बिंदु पर अर्धविराम छोड़ आवश्यकता है, लेकिन do { } while(0) आप एक असली समारोह के लिए के रूप में बिल्कुल एक ही वाक्य विन्यास का उपयोग करने देता है।

(ब्लॉक निर्माण के किसी भी प्रकार का उपयोग कर बिल्कुल नहीं सिर्फ पूरी तरह से टूटी हुई कोड उत्पन्न होता है, natch)

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