If-else ब्लॉक में 'if (0)' ब्लॉक का उद्देश्य क्या है?


141

मेरा प्रश्न उस पंक्ति के बारे में है जिसका मैंने विषय में उल्लेख किया है और जिसे मैं उत्पादन कोड के अंदर कई स्थानों पर देख सकता हूं।

समग्र कोड इस तरह दिखता है:

if (0) {
    // Empty braces
} else if (some_fn_call()) {
    // actual code
} else if (some_other_fn_call()) {
    // another actual code
    ...
} else {
    // default case
}

अन्य शाखाएँ मेरे प्रश्न के लिए अप्रासंगिक हैं। मैं सोच रहा हूँ कि if (0)यहाँ डालने का अर्थ क्या है। ब्रेसिज़ खाली हैं, इसलिए मुझे नहीं लगता कि यह कोड के कुछ ब्लॉक पर टिप्पणी करना चाहिए। क्या यह संकलक को कुछ अनुकूलन करने के लिए मजबूर करता है या इसके इरादे अलग हैं?

मैंने एसओ और इंटरनेट पर इस स्पष्ट मामले की खोज करने की कोशिश की है, लेकिन कोई सफलता नहीं मिली। जावास्क्रिप्ट के बारे में भी ऐसे ही सवाल हैं, लेकिन नहीं। सी। एक और सवाल है, जब एक शून्य को `if 'स्थिति में सौंपा जाता है , तो क्या होता है? , लेकिन यह एक चर के लिए शून्य असाइनमेंट पर चर्चा करता है, न कि 'if (0)' के उपयोग के लिए।


2
यह कथन अप्रासंगिक लगता है। उस कथन के साथ और उसके बिना असेंबली कोड बनाएं और आप देखेंगे कि हुड के नीचे क्या हो रहा है।
9

2
यह संभव है कि यह स्वचालित रूप से उत्पन्न कोड है।
अजीब

जवाबों:


91

मैं कभी-कभी समरूपता के लिए इसका उपयोग करता हूं, इसलिए मैं else if{अपने संपादक के साथ दूसरे को स्वतंत्र रूप से चारों ओर स्थानांतरित कर सकता हूं, पहले ध्यान में रखे बिनाif

शब्दार्थ

if (0) {
    // Empty braces
} else 

भाग कुछ भी नहीं करता है और आप इसे हटाने के लिए ऑप्टिमाइज़र पर भरोसा कर सकते हैं।


239
व्यक्तिगत राय: हालांकि यह कारण कोड हो सकता है कि यह क्यों लिखा गया है, मुझे लगता है कि यह एक गलत औचित्य है। कोड को लिखे जाने की तुलना में अधिक बार पढ़ा जाता है, और यह अनावश्यक कोड पाठक के लिए बस ओवरहेडिंग बढ़ाता है।
user694733

13
@ user694733: आप तर्क दे सकते हैं कि if elseसभी महत्वपूर्ण कोड पथों के लिए सामान्य उपसर्ग शर्तों को अच्छी तरह से पंक्तिबद्ध करता है और उन्हें स्कैन करना आसान बनाता है। (यह व्यक्तिपरक है, हालांकि, यह बहुत कुछ निर्भर करेगा कि वास्तव में स्थितियों और कोड ब्लॉकों के अंदर क्या है।)
एम ओहम

72
मुझे नहीं लगता कि if (0) {..}कोई भी पार्सबिलिटी / पठनीयता समस्या का परिचय देता है। यह किसी को भी स्पष्ट होना चाहिए जो सी के बारे में थोड़ा जानता है। यह कोई मुद्दा नहीं है। समस्या यह पढ़ने के बाद का सवाल है: "इसके बाद क्या है?" जब तक यह डिबगिंग / अस्थायी उद्देश्यों के लिए नहीं है (यानी, इरादा ifबाद में उस ब्लॉक को "सक्षम" करना है), मैं पूरी तरह से हटाने की वकालत करूंगा । मूल रूप से इस तरह के कोड को "पढ़ने" से पाठक को बिना किसी अच्छे कारण के अनावश्यक "विराम" की संभावना होती है। और इसे दूर करने के लिए एक अच्छा पर्याप्त कारण है।
पीपी

77
ऐसा लगता है कि यह निश्चित रूप से पठनीयता से अलग है। यह इतना बुरा था कि एसओ को उस प्रोग्रामर को यह पूछने के लिए भेजा कि यह क्या है। अच्छा संकेत नहीं।
वेक्टरजोन

26
यहां तक कि इस पद्धति का उपयोग कर, मैं यदि आप "स्थानांतरित कर सकते हैं पता नहीं है else ifक्योंकि स्थिति परस्पर अनन्य नहीं हो सकता है चारों ओर संपादक चिंता किए बिना", जिसमें मामले आदेश मायने रखती है। व्यक्तिगत रूप से मैं केवल उपयोग करता हूं if, और यदि आवश्यक हो तो तर्क श्रृंखला को एक अलग फ़ंक्शन में निकालते हुए, जल्दी वापसी करता हूं ।
जॉन वू

105

#ifबयान, आल्हा हो तो यह उपयोगी हो सकता है

   if (0)
   {
       // Empty block
   }
#if TEST1_ENABLED
   else if (test1())
   {
      action1();
   }
#endif
#if TEST2_ENABLED
   else if (test2())
   {
      action2();
   }
#endif

आदि।

इस मामले में, परीक्षणों में से कोई भी (और सभी) #if'एड' हो सकता है, और कोड सही ढंग से संकलित करेगा। लगभग सभी संकलक if (0) {}भाग को हटा देंगे । एक साधारण ऑटोगेनेरेटर इस तरह कोड उत्पन्न कर सकता है, क्योंकि यह कोड को थोड़ा आसान है - इसे अलग से पहले सक्षम ब्लॉक पर विचार करने की आवश्यकता नहीं है।


5
कई मामलों में, एक if/ else ifश्रृंखला का उपयोग निर्णय के पेड़ के रूप में नहीं किया जाता है, बल्कि एक "पहले मिलान स्थिति पर कार्य" निर्माण के रूप में किया जाता है, जहां सर्वोच्च प्राथमिकता वाले होने वाली स्थिति विशेष रूप से "विशेष" नहीं है। हालांकि मैंने if(0)सभी वास्तविक शाखाओं को संगत सिंटैक्स की अनुमति देने के तरीके के रूप में उपयोग नहीं किया है, मुझे यह संगत सिंटैक्स पसंद है जो इसे सुविधाजनक बनाता है।
सुपरकाट

1
यह इस मामले में भी उपयोगी नहीं है क्योंकि आप इसके बिना एक ही प्रभाव प्राप्त कर सकते हैं: बस else ifलाइन को दो में विभाजित करें और बीच में प्रीप्रोसेसर गार्ड लगाएं।
कोनराड रुडोल्फ

1
@KonradRudolph मैं अनुसरण नहीं कर रहा हूँ; आप इसे कैसे लिखेंगे?
जिंक

1
@JiK मैं if (0)शाखा और सुधारक को हटा दूंगा , जो कि elseअपनी लाइन पर है, एक गार्ड द्वारा घिरा हुआ है #if TEST1_ENABLED && TEST2_ENABLED
कोनराड रुडोल्फ

5
@KonradRudolph यह ठीक है कि यदि आप गार्ड की संख्या को दोगुना करना चाहते हैं और बताई गई गार्ड की संख्या को तीन गुना कर दें, मुझे लगता है।
हॉब्स

44

मैंने एक समान पैटर्न उत्पन्न कोड में उपयोग किया है। उदाहरण के लिए, एसक्यूएल में, मैंने देखा है कि पुस्तकालयों में निम्न whereखंड का उत्सर्जन होता है ।

where 1 = 1

यह संभवतः अन्य मानदंडों पर जोड़ने के लिए आसान बनाता है, क्योंकि अतिरिक्त मानदंड के andबजाय सभी अतिरिक्त मानदंड पूर्व निर्धारित किए जा सकते हैं, यह देखने के लिए कि यह पहला मानदंड है या नहीं।


4
1=1क्योंकि तुम हमेशा जोड़ सकते हैं भी "उपयोगी" है whereसामने, बिना शर्त। अन्यथा आपको यह देखना होगा कि क्या यह खाली है, और यदि ऐसा है तो whereक्लॉज जनरेट करने से बचें ।
बकुरीउ

2
इसके अलावा, ज्यादातर डेटाबेस स्वचालित रूप से "निकालें" जाएगा 1=1से WHERE, तो यह प्रदर्शन पर प्रभाव पड़ता है नहीं करता है।
निधि मोनिका का मुकदमा

7
यह एक पुस्तकालय में स्वीकार्य है जो स्वचालित रूप से SQL क्वेरी उत्पन्न करता है जो सबसे अधिक संभावना है कि कभी भी DevOps टीम द्वारा नहीं देखा जाता है। यह उच्च-स्तरीय कोड में "स्वीकार्य" नहीं है जिसे कई बार लिखा और पढ़ा जाना है।
फागियो

अज्ञात स्थितियों में अंतिम स्थिति के साथ कुछ प्रकार के गतिशील SQL उत्पन्न करते समय यह वास्तव में आसान तरीका है ।
स्कीपर

1
@ वास्तव में मैंने इसके विपरीत लिखा है: खराब पठनीय वाक्यविन्यास उत्पन्न कोड में स्वीकार्य है क्योंकि यह सबसे अधिक संभावना कभी नहीं पढ़ा जाएगा, डेवलपर्स द्वारा बनाए रखा गया उच्च-स्तरीय कार्यात्मक कोड में नहीं।
फागियो

44

जैसा कि लिखा गया है, if (0) {}खंड कुछ भी नहीं करने के लिए संकलित करता है।

मुझे संदेह है कि इस सीढ़ी के शीर्ष 0पर एक 1या एक से बदलकर एक बार (डिबगिंग या तुलना उद्देश्यों के लिए) अन्य सभी कार्यक्षमता को अस्थायी रूप से अक्षम करने के लिए एक आसान स्थान प्रदान करना है true


2
बिल्कुल सही किया। मैं डिबगिंग के पास कोई अन्य कारण नहीं देख सका।
tfont

16

मुझे किसी भी अनुकूलन का यकीन नहीं है, लेकिन मेरे दो सेंट:

यह कुछ कोड संशोधन के कारण हुआ, जहां एक प्राथमिक स्थिति को हटा दिया गया था, (शुरुआती ifब्लॉक में फ़ंक्शन कॉल , मान लें), लेकिन डेवलपर्स / अनुरक्षक

इसलिए संबंधित ifब्लॉक को हटाने के बजाय , उन्होंने बस शर्त को बदल दिया if(0)और आगे बढ़ गए।


3
if(0)शाखा कवरेज में भी कमी नहीं है?
डेविड सज़ालई

1
@DavidSzalai पूरी तरह से नहीं - कम से कम यह 1 (पिछले 2 से) से कम हो जाएगा - लेकिन मेरे ज्ञान के सर्वश्रेष्ठ के लिए कवरेज के लिए एक हिट अभी भी आवश्यक होगी।
सौरव घोष

15

यह कोड रोट है।

कुछ बिंदु पर कि "अगर" कुछ उपयोगी था, तो स्थिति बदल गई, शायद मूल्यांकन किए जा रहे चर को हटा दिया गया था।

जो व्यक्ति सिस्टम को ठीक कर रहा था / बदल रहा था उसने सिस्टम के तर्क को प्रभावित करने के लिए जितना संभव हो उतना कम किया ताकि वह सुनिश्चित करे कि कोड फिर से शुरू हो जाएगा। इसलिए वह एक "if (0)" छोड़ देता है क्योंकि वह त्वरित और आसान है और वह पूरी तरह से निश्चित नहीं है कि वह क्या करना चाहता है। उसे काम करने की प्रणाली मिलती है और वह इसे पूरी तरह से ठीक करने के लिए वापस नहीं जाता है।

फिर अगला डेवलपर साथ आता है और सोचता है कि यह जानबूझकर किया गया था और केवल कोड के उस हिस्से पर टिप्पणी करता है (चूंकि इसका मूल्यांकन वैसे भी नहीं किया जा रहा है), फिर अगली बार कोड को छूने पर उन टिप्पणियों को हटा दिया जाता है।


2
हाँ। प्राचीन कोड के लिए, एक बार में एक मृत-कोड-हटाने वाला परिवर्तन करें। मैं केवल "मृत" कोड के खिलाफ एक स्लेश-एंड-बर्न हिसा पर चला गया है की संख्या की गणना नहीं कर सकता है केवल यह पता लगाने के लिए कि कुछ विचित्र साइड-इफेक्ट था जो स्लैश-एंड-बर्निंग मिस हो गया।
ऑस्टिन

15

एक संभावना अभी तक उल्लेख नहीं किया गया है: द if (0) { रेखा एक ब्रेकपॉइंट के लिए एक सुविधाजनक स्थान प्रदान कर सकती है।

डिबगिंग अक्सर गैर-अनुकूलित कोड पर किया जाता है, इसलिए हमेशा-गलत परीक्षण मौजूद होगा और उस पर सेटपॉइंट सेट करने में सक्षम होगा। जब उत्पादन के लिए संकलित किया जाता है, तो कोड की लाइन को अनुकूलित किया जाएगा। प्रतीत होता है बेकार लाइन विकास के लिए कार्यक्षमता देती है और रिलीज बिल्ड को प्रभावित किए बिना परीक्षण का निर्माण करती है।

ऊपर अन्य अच्छे सुझाव भी हैं; एकमात्र तरीका वास्तव में यह जानना है कि उद्देश्य क्या है, लेखक को ट्रैक करना और पूछना। आपका सोर्स कोड कंट्रोल सिस्टम इसमें मदद कर सकता है। ( blameटाइप कार्यक्षमता के लिए देखें।)


9

मैंने पहले से विस्तारित जावास्क्रिप्ट में गैर-पहुंच योग्य कोड ब्लॉक देखे हैं जो एक अस्थायी भाषा का उपयोग करके उत्पन्न किए गए हैं।

उदाहरण के लिए, आप जो कोड पढ़ रहे हैं, वह उस सर्वर से चिपकाया जा सकता है, जिसने उस स्थिति में पहले मूल्यांकन किया था, जो उस समय केवल सर्वर पर उपलब्ध चर पर निर्भर था।

if ( ${requestIsNotHttps} ){ ... }else if( ...

जो एक बार पूर्व-संकलित हो जाता है:

if ( 0 ){ ... }else if ( ...

आशा है कि यह आपको प्रो-रीसाइक्लिंग कोडर्स युग की संभावित कम कीबोर्ड गतिविधि को पुनः प्राप्त करने में मदद करता है जिसके लिए मैं उत्साह प्रकट करता हूं!


1
मैं मानता हूं, सर्वव्यापी स्वचालन के युग में हमें ऑटोगेनेरेटेड कोड पर अधिक भरोसा करना चाहिए, क्योंकि यह हमें वास्तविक चीजों पर अधिक समय बिताने की अनुमति देता है। लेकिन अब के लिए, मेरी दिलचस्पी का सटीक बिंदु यह है कि यह सब कुछ कैसे हुड के तहत वास्तुकला है।
Zzaponka

8

इस प्रकार का उपयोग C में जेनेरिक प्रोग्रामिंग को सुरक्षा के साथ लागू करने के लिए भी किया जा सकता है, इस तथ्य पर भरोसा करते हुए कि संकलक द्वारा अनुपलब्ध कोड अभी भी जांचा जाता है:

// this is a generic unsafe function, that will call fun(arg) at a later time
void defer(void *fun, void *arg);

// this is a macro that makes it safer, by checking the argument
// matches the function signature
#define DEFER(f, arg) \
   if(0) f(arg); \              // never actually called, but compile-time checked
   else defer(f, (void *)arg);  // do the unsafe call after safety check

void myfunction(int *p);

DEFER(myfunction, 42);     // compile error
int *b;
DEFER(myfunction, b);      // compiles OK

6

मुझे लगता है कि यह सिर्फ बुरा कोड है। कंपाइलर एक्सप्लोरर में एक त्वरित उदाहरण लिखते हुए, हम देखते हैं कि जीसीसी और क्लैंग दोनों में if (0)ब्लॉक के लिए कोई कोड उत्पन्न नहीं होता है , यहां तक ​​कि अनुकूलन पूरी तरह से अक्षम होने के साथ:

https://godbolt.org/z/PETIks

if (0)जनरेट किए गए कोड में कोई परिवर्तन नहीं करने के कारणों को दूर करने के साथ खेल रहा है, इसलिए मैं यह निष्कर्ष निकालता हूं कि यह अनुकूलन नहीं है।

यह संभव है कि शीर्ष ifब्लॉक में कुछ हुआ करता था जिसे बाद में हटा दिया गया था। संक्षेप में, ऐसा लगता है कि इसे हटाने से ठीक उसी कोड को उत्पन्न किया जाएगा, इसलिए ऐसा करने के लिए स्वतंत्र महसूस करें।


6

जैसा कि कहा गया है, शून्य का मूल्यांकन असत्य से किया जाता है, और संभवतः संकलक द्वारा शाखा को अनुकूलित किया जाएगा।

मैंने इसे पहले भी कोड में देखा है जहां एक नई सुविधा जोड़ी गई थी और एक किल-स्विच की आवश्यकता थी (यदि कुछ सुविधा के साथ गलत हो जाता है तो आप इसे बंद कर सकते हैं), और कुछ समय बाद जब किल-स्विच को हटा दिया गया था प्रोग्रामर ने शाखा को भी नहीं हटाया, उदा

if (feature_a_active()) {
    use_feature_a();
} else if (some_fn()) {
   ...

बन गया

if (0) {
   // empty
} else if (some_fn()) {
   ...

1

यह ब्लॉक को ब्लॉक करने में मदद करता है, अगर ब्लॉक 1। और भी अगर हम ब्लॉक का विस्तार कर सकते हैं।


1
    Actually according to my opinion, if we put any variable for checking inside
    e.g:-
public static void main(string args[])
{
        var status;
        var empList=_unitofWork.EmpRepository.Get(con=>con.isRetired==true);
        //some code logic 
        if(empList.count>0)
        {
          status=true;
        }
        if(status)
        {
         //do something
        }
        else
        {
        //do something else
        }
}
     if then its dynamically get the value in run time and invoke the logic inside it, else its simply extra line of code i guess.

    Anybody have any depth knowledge why this thing is used....or agree with me.
    kindly respond. 

1

@ PSkocik का जवाब ठीक है, लेकिन मैं अपने दो सेंट जोड़ देता हूं। यदि मुझे यह टिप्पणी के रूप में करना चाहिए, या उत्तर के रूप में; बाद वाले को चुनना, क्योंकि IMHO दूसरों को देखने लायक है, जबकि टिप्पणियां अक्सर अदृश्य होती हैं।

इतना ही नहीं मैं कभी-कभार इस्तेमाल करता हूं

if(0) {
   //deliberately left empty
} else if( cond1 ) {
   //deliberately left empty
} else if( cond2 ) {
   //deliberately left empty
...
} else {
   // no conditions matched
}

लेकिन मैं भी कभी-कभार करता हूं

if( 1 
    && cond1 
    && cond2
    ...
    && condN
) {

या

if( 0 
    || cond1 
    || cond2
    ...
    || condN
) {

जटिल परिस्थितियों के लिए। समान कारणों से - संपादित करने में आसान, # हाइफ़, आदि।

उस मामले के लिए, मैं पर्ल में करूंगा

@array = (  
    elem1,
    elem2,
    ...
    elem1,
) {
  • सूची के अंत में अल्पविराम पर ध्यान दें। मैं भूल जाता हूं कि क्या कॉमा सी और सी ++ सूची में विभाजक या सीमांकक हैं। IMHO यह एक चीज है जिसे हमने सीखा है: [ क्या पर्ल में कॉलिंग करना एक बुरा व्यवहार है? अल्पविराम] एक अच्छी बात है। किसी भी नए संकेतन की तरह, इसकी आदत पड़ने में थोड़ा समय लगता है।

मैं तुलना करता हूं if(0) कोड की लिस्प से

(cond   (test1    action1)
   (test2    action2)
   ...
   (testn   actionn))

जो, आप यह अनुमान लगाया, मैं के रूप में इंडेंट कर सकते हैं

(cond   
   (test1    action1)
   (test2    action2)
   ...
   (testn   actionn)
)

मैंने कभी-कभी यह कल्पना करने की कोशिश की है कि इसके लिए एक अधिक मानव पठनीय वाक्यविन्यास कैसा दिख सकता है।

शायद

IF
:: cond1 THEN code1
:: cond2 THEN code2
...
:: condN THEN codeN
FI

द्वारा Dikstra के [प्रेरित https://en.wikipedia.org/wiki/Guarded_Command_Language#Selection:_if][Guarded Command Language] ।

लेकिन यह वाक्यविन्यास बताता है कि स्थितियों का मूल्यांकन समानांतर में किया जाता है, जबकि if...else-if इसका का अनुक्रमिक और प्राथमिकता मूल्यांकन।

मैंने ऐसे कार्यक्रम करना शुरू कर दिया, जब अन्य कार्यक्रमों को बनाने वाले कार्यक्रमों को लिखना, जहां यह विशेष रूप से सुविधाजनक है।

जब हम इस पर होते हैं, जब इंटेल के पुराने iHDL का उपयोग करके RTL लिखते हैं, तो मेरे पास कोडित सामान होता है

   IF 0 THEN /*nothing*/
   **FORC i FROM 1 TO 10 DOC** 
   ELSE IF signal%i% THEN    
      // stuff to do if signal%i% is active
   **ENDC** 
   ELSE   
      // nothing matched 
   ENDIF

जहां FORC..DOC..ENDCमैक्रो प्रीप्रोसेसर लूप कंस्ट्रक्शन है, जो विस्तार करता है

   IF 0 THEN /*nothing*/
   ELSE IF signal1 THEN    
      // stuff to do if signal1 is active
   ELSE IF signal2 THEN    
      // stuff to do if signal2 is active
   ...
   ELSE IF signal100 THEN    
      // stuff to do if signal100 is active
   ELSE   
      // nothing matched 
   ENDIF

यह एकल असाइनमेंट, गैर-अनिवार्य, कोड था, इसलिए राज्य चर सेट करने की अनुमति नहीं थी, यदि आपको कुछ सेट बिट जैसे चीजें करने की आवश्यकता होती है।

   IF 0 THEN /*nothing*/
   ELSE IF signal1 THEN    
      found := 1
   ELSE IF signal2 THEN    
      found := 2
   ...
   ELSE IF signal100 THEN    
      found := 100
   ELSE   
      // nothing matched 
   ENDIF

यह सोचने के लिए आओ, यह पहला स्थान हो सकता है कि मुझे इस तरह के निर्माण का सामना करना पड़ा।

BTW, आपत्ति है कि कुछ अगर (0) शैली के लिए था - कि अन्य-अगर-शर्तें क्रमिक रूप से निर्भर हैं और मनमाने ढंग से पुन: व्यवस्थित नहीं किया जा सकता - आरटीएल में AND और OR और XOR तर्क पर लागू नहीं होते हैं - लेकिन लघु- पर लागू होते हैं सर्किट && और ||


-1

मैंने उदाहरण के लिए त्रुटियों को संभालने के लिए इसका उपयोग किया है

if(0){
lable1:
   //do something
}
if(0){
lable2:
   //do something
}
.
.
and so on.

if(condition_fails)
   goto lable1;

यह तब मददगार हो सकता है जब त्रुटियों को प्रबंधित करने के लिए गोटो का उपयोग किया जाता है, केवल एक त्रुटि होने पर बयान निष्पादित किए जाते हैं। मैंने इसे बहुत पुराने सी-कोड में देखा था (जहाँ फ़ंक्शन तर्क '()' के बाहर लिखे गए हैं), अब किसी को भी इसका अनुसरण नहीं करना चाहिए।


-2

मैंने इसे कई बार देखा है, मुझे लगता है कि सबसे संभावित कारण यह है कि यह कोड के पुराने / अलग संस्करण / शाखा में कुछ का मूल्यांकन कर रहा था, या संभवतः डिबगिंग के लिए, और इसे बदलने if(0)से जो कुछ भी था उसे हटाने का एक आलसी तरीका है ।

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