वास्तव में एक #if 0 ... #endif ब्लॉक क्या करता है?


124

में सी / सी ++

क्या होता है #if 0/ a #endifब्लॉक के बीच रखा कोड ?

#if 0

//Code goes here

#endif

क्या कोड बस छूट जाता है और इसलिए निष्पादित नहीं होता है?


17
यह एक तकनीक है जिसका उपयोग कोड की बड़ी मात्रा में टिप्पणी करने या कोड के ब्लॉक को शामिल करने की अनुमति देने के लिए किया जाता है। इस सुविधा के बिना, किसी को प्रत्येक पंक्ति के साथ उपसर्ग करना होगा //या अनुभाग को शुरू करना होगा और अनुभाग को /*समाप्त करना होगा */। बाद की तकनीकों के साथ समस्या यह है कि टिप्पणी की घोंसला नहीं है इसलिए डेवलपर को */शुरू और अंत के बीच किसी भी चीज को जांचना और संभालना चाहिए ।
थॉमस मैथ्यू

जवाबों:


141

इतना ही नहीं निष्पादित नहीं करता है, यह भी संकलित नहीं करता है।

#ifएक प्रीप्रोसेसर कमांड है, जिसका मूल्यांकन वास्तविक संकलन चरण से पहले किया जाता है। उस ब्लॉक के अंदर कोड संकलित बाइनरी में दिखाई नहीं देता है।

यह अक्सर बाद में उन्हें वापस करने के इरादे से कोड के सेगमेंट को अस्थायी रूप से हटाने के लिए उपयोग किया जाता है।


1
यह किसी भी तरह की टिप्पणी का सच है। महत्वपूर्ण अंतर नेस्टिंग है।
सैमी बेनचेरीफ

73

यह ब्लॉक के बारे में टिप्पणी करने के समान है, एक महत्वपूर्ण अंतर को छोड़कर: घोंसला बनाना कोई समस्या नहीं है। इस कोड पर विचार करें:

foo();
bar(x, y); /* x must not be NULL */
baz();

अगर मैं इसे टिप्पणी करना चाहता हूं, तो मैं कोशिश कर सकता हूं:

/*
foo();
bar(x, y); /* x must not be NULL */
baz();
*/

Bzzt। वक्य रचना त्रुटि! क्यों? क्योंकि ब्लॉक टिप्पणियां घोंसला नहीं बनाती हैं, और इसलिए (जैसा कि आप SO के सिंटैक्स हाइलाइटिंग से देख सकते हैं) */शब्द के बाद "NULL" टिप्पणी को समाप्त कर देता है, जिससे bazकॉल टिप्पणी नहीं होती है, और एक सिंटैक्स त्रुटि के */बाद baz। दूसरी ओर:

#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif

पूरी बात बताने के लिए काम करता है। और #if 0एस एक दूसरे के साथ घोंसला बनाएगा, जैसे:

#if 0
pre_foo();
#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif
quux();
#endif

हालांकि निश्चित रूप से यह थोड़ा भ्रामक हो सकता है और अगर ठीक से टिप्पणी नहीं की जाती है तो रखरखाव सिरदर्द बन सकता है।


5
बस ध्यान दें कि #if के अंदर का कोड lexically सही होना चाहिए (टिप्पणियों के विपरीत) और प्रीप्रोसेसर निर्देश अभी भी प्रभाव में हैं (ditto)।
jpalecek

@ डेविड: इसका शाब्दिक रूप से सही नहीं है, लेकिन यह अभी भी संकलन करेगा। इसलिए कोड को शाब्दिक रूप से सही नहीं होना चाहिए।
डेनिस ज़िकफ़ोज़

1
@ डेनिस, मुझे foo.c:3: unterminated string or character constantजीसीसी से मिलता है, आप क्या उपयोग कर रहे हैं?
डेविड एक्स

18

यह स्थायी रूप से उस कोड को टिप्पणी करता है ताकि संकलक इसे कभी संकलित न करे।

कोडर बाद में #ifdef को बदल कर उस कोड को प्रोग्राम में संकलित कर सकता है यदि वह चाहता है।

यह ठीक उसी तरह है जैसे कोड मौजूद नहीं है।


15

वास्तव में एक #if 0 ... #endif ब्लॉक क्या करता है?

यह बताता है कि लेखक ने स्पष्ट रूप से संस्करण नियंत्रण प्रणाली के बारे में कभी नहीं सुना है। जो बदले में, आपको यथासंभव…


12

मैं इस #elseमामले में जोड़ना चाहूंगा :

#if 0
   /* Code here will NOT be complied. */
#else
   /* Code will be compiled. */
#endif


#if 1
   /* Code will be complied. */
#else
   /* Code will NOT be compiled. */
#endif

7

जब प्रीप्रोसेसर #if देखता है तो यह जाँचता है कि क्या अगले टोकन का गैर-शून्य मान है। यदि ऐसा होता है, तो यह कोड को कंपाइलर के लिए चारों ओर रखता है। यदि ऐसा नहीं होता है, तो उसे उस कोड से छुटकारा मिल जाता है इसलिए कंपाइलर उसे कभी नहीं देखता है।

अगर कोई कहता है कि # आईएफ 0 वे कोड को प्रभावी ढंग से टिप्पणी कर रहे हैं, इसलिए इसे कभी भी संकलित नहीं किया जाएगा। आप इसके बारे में ऐसा ही सोच सकते हैं जैसे कि उन्होंने / * ... * / इसके आसपास रखा हो। यह काफी समान नहीं है, लेकिन इसका प्रभाव समान है।

यदि आप यह समझना चाहते हैं कि विस्तार से क्या हुआ, तो आप अक्सर देख सकते हैं। कई संकलक आपको प्रीप्रोसेसर चलाने के बाद फ़ाइलों को देखने की अनुमति देंगे। उदाहरण के लिए, Visual C ++ पर स्विच / P कमांड प्रीप्रोसेसर को निष्पादित करेगा और परिणामों को एक .i फ़ाइल में डालेगा।


काफी नहीं। पूर्वप्रक्रमक टोकन के बजाय लाइन द्वारा पार्स करता है। आपके स्पष्टीकरण के अनुसार यह कहना संभव नहीं होगा, #if WIN32 || __CYGWIN__लेकिन यह उम्मीद के मुताबिक काम करता है।
बेन वोइगट

मैं सरलीकरण कर रहा था। यदि कोई है या, यह जाँच करेगा कि क्या टोकन गैर-शून्य है। इसी तरह अगर वहाँ है और यह जाँच करेगा कि क्या दोनों गैर-शून्य हैं।
स्टीव रोवे

3

एक के साथ शुरुआत लाइन्स #हैं पूर्वप्रक्रमक निर्देशों#if 0 [...] #endifब्लॉक इसे संकलक के लिए नहीं बनाते हैं और कोई मशीन कोड उत्पन्न नहीं करेंगे।

आप एक स्रोत फ़ाइल के साथ प्रीप्रोसेसर के साथ क्या होता है यह प्रदर्शित कर सकते हैं ifdef.cxx:

#if 0
This code will not be compiled
#else
int i = 0;
#endif

चल रहा है gcc -E ifdef.cxx आपको दिखाएगा कि क्या संकलित है।

आप विकास चक्र के दौरान संकलित किए जा रहे कोड के एक ब्लॉक को रोकने के लिए इस तंत्र का उपयोग करने का चयन कर सकते हैं, लेकिन आप शायद इसे अपने स्रोत नियंत्रण में नहीं देखना चाहेंगे क्योंकि यह आपके कोड में cruft जोड़ता है और पठनीयता को कम करता है। यदि यह कोड का एक ऐतिहासिक टुकड़ा है जिस पर टिप्पणी की गई है, तो इसे हटा दिया जाना चाहिए: स्रोत नियंत्रण में इतिहास शामिल है, है ना?

साथ ही, उत्तर C और C ++ दोनों के लिए समान हो सकता है, लेकिन C / C ++ नाम की कोई भाषा नहीं है और ऐसी भाषा का संदर्भ देना अच्छी आदत नहीं है।


4
"C या C ++" के लिए शॉर्टहैंड के रूप में C / C ++ कहने में क्या गलत है? क्या आप ईमानदारी से सोचते हैं कि कोई भी यह सोचकर भ्रमित होने वाला है कि "C / C ++" नामक कोई भाषा है?
क्रिस्टोफर नाई

1
@ क्रिस: लोग लगातार सवाल पूछते हैं "मैं सी / सी ++ में एक्स कैसे करता हूं?" जो एक निरर्थक प्रश्न है; आप एक या दूसरे में कोडिंग कर रहे हैं, और यदि आपने अभी तक नहीं चुना है, तो आपको उस तथ्य में स्पष्ट होना चाहिए। तो, हाँ, लोग "सी / सी ++" नामक एक भाषा होने के बारे में उलझन में हैं
डेनिस ज़िकॉफोज

1
क्या बकवास बयान है! ऐसे हजारों प्रश्न हैं जिनके उत्तर C और C ++ दोनों के लिए प्रासंगिक हैं। याद रखें कि यह प्रश्न पूछने के लिए एक साइट है। सिर्फ इसलिए कि आप एक सामान्य प्रश्न पूछ रहे हैं इसका मतलब यह नहीं है कि आप नहीं जानते कि आप किस भाषा का उपयोग कर रहे हैं। यदि आपको संदेह है कि मामला है, तो इस सवाल के रूप में, यह C या C ++ को निर्दिष्ट करने में कैसे मदद करता है? क्या आपको लगता है कि यह मददगार होगा यदि प्रत्येक प्रश्न जो C या C ++ पर लागू हो, दो बार पूछा जा सकता है?
क्रिस्टोफर नाई

@Christopher: आप सही हैं, ऐसे कई प्रश्न हैं, जिनके उत्तर C, C ++ और Objective-C (यह उनमें से एक होने के नाते) के लिए प्रासंगिक हैं। स्टैक ओवरफ्लो में एक उपयोगी टैगिंग सिस्टम है जिससे यह पता लगाया जा सकता है कि प्रश्न किन भाषाओं का है। जैसा कि @ डेनिस का उल्लेख है, एसओ (और अन्य प्रोग्रामिंग फ़ोरम [fora?]) वहाँ (भी) कई लोग हैं जो सी और अन्य सी-व्युत्पन्न भाषाओं के बीच के भ्रम के रूप में भ्रमित हैं जो इन भाषाओं को परस्पर विनिमय के रूप में C / C ++ के रूप में बनाते हैं। उचित भाषा में प्रश्न का उत्तर देना कठिन है।
जॉन्सवेब

2

काफी नहीं

int main(void)
{
   #if 0
     the apostrophe ' causes a warning
   #endif
   return 0;
}

यह "tc: 4: 19: चेतावनी: लापता '' चरित्र" को gcc 4.2.4 के साथ दिखाता है


2
यह चेतावनी प्रीप्रोसेसर द्वारा निर्मित होती है, संकलक के द्वारा नहीं। कंपाइलर केवल देखने के लिए मिलता है: # 1 "टीसी" # 1 "<अंतर्निहित>" # 1 "<कमांड-लाइन>" # 1 "टीसी" इंट मुख्य (शून्य) {वापसी 0; }
जॉन्सवेब

0

यह टिप्पणी करने का एक सस्ता तरीका है, लेकिन मुझे संदेह है कि इसमें डिबगिंग की क्षमता हो सकती है। उदाहरण के लिए, मान लें कि आपके पास एक फ़ाइल के लिए आउटपुट मान है। आप नहीं चाहेंगे कि अंतिम संस्करण में आप # 0 का उपयोग कर सकें ... #endif।

इसके अलावा, मुझे डिबग उद्देश्य के लिए इसे करने के एक बेहतर तरीके पर संदेह है:

#ifdef DEBUG
// output to file
#endif

आप ऐसा कुछ कर सकते हैं और यह अधिक समझ में आता है और परिणाम देखने के लिए आपको केवल DEBUG को परिभाषित करना होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.