गैर-शून्य विधि में अनुपलब्ध रिटर्न स्टेटमेंट संकलित करता है


189

मुझे एक ऐसी स्थिति का सामना करना पड़ा जहां एक गैर-शून्य विधि रिटर्न स्टेटमेंट याद कर रही है और कोड अभी भी संकलित है। मुझे पता है कि लूप के बाद के बयान अप्राप्य (मृत कोड) हैं और कभी भी निष्पादित नहीं किए जाएंगे। लेकिन संकलक भी कुछ वापस करने के बारे में चेतावनी क्यों नहीं देता है? या क्यों एक भाषा हमें एक गैर-शून्य विधि होने की अनुमति देगी जिसमें एक अनंत लूप हो और कुछ भी वापस न हो?

public int doNotReturnAnything() {
    while(true) {
        //do something
    }
    //no return statement
}

यदि मैं एक लूप स्टेटमेंट (यहां तक ​​कि एक सशर्त एक) को लूप में जोड़ता हूं, तो कंपाइलर कुख्यात त्रुटियों की शिकायत करता है: Method does not return a valueग्रहण और Not all code paths return a valueदृश्य स्टूडियो में।

public int doNotReturnAnything() {
    while(true) {
        if(mustReturn) break;
        //do something
    }
    //no return statement
}

यह जावा और C # दोनों का सच है।


3
अच्छा प्रश्न। मुझे इसके कारण में दिलचस्पी होगी।
एरिक शियरबॉम

18
एक अनुमान: यह एक अनंत लूप है, इसलिए एक वापसी नियंत्रण प्रवाह अप्रासंगिक है?
ल्यूस थेरिन

5
"एक भाषा हमें एक अनौपचारिक विधि की अनुमति क्यों देगी जिसमें एक अनंत लूप हो और कुछ भी वापस न हो?" <- जबकि मूर्खतापूर्ण लग रहा है, सवाल भी उलट हो सकता है: यह अनुमति क्यों नहीं दी जाएगी? क्या यह वास्तविक कोड है, वैसे?
fge

3
जावा के लिए, आप इस उत्तर में एक अच्छी व्याख्या पा सकते हैं ।
केपील

4
जैसे दूसरों ने समझाया है, ऐसा इसलिए है क्योंकि लूप अनंत है यह जानने के लिए कंपाइलर काफी स्मार्ट है। ध्यान दें कि संकलक न केवल रिटर्न को गायब होने की अनुमति देता है, यह इसे लागू करता है क्योंकि यह लूप अगम्य होने के बाद कुछ भी जानता है। कम से कम नेटबीन्स में, यह शाब्दिक रूप से शिकायत करेगा unreachable statementकि क्या लूप के बाद कुछ है
सुप्र

जवाबों:


240

एक भाषा हमें एक अनौपचारिक विधि की अनुमति क्यों देती है जिसमें एक अनंत लूप होता है और कुछ भी वापस नहीं होता है?

गैर-शून्य विधियों के लिए नियम हर कोड पथ है जो रिटर्न को एक मान लौटाता है , और यह नियम आपके कार्यक्रम में संतुष्ट है: शून्य से बाहर शून्य कोड पथ जो वापसी करते हैं एक मान वापस करते हैं। नियम यह नहीं है कि "प्रत्येक गैर-शून्य विधि में एक कोड पथ होना चाहिए जो रिटर्न करता है"।

यह आपको स्टब-तरीके लिखने में सक्षम बनाता है जैसे:

IEnumerator IEnumerable.GetEnumerator() 
{ 
    throw new NotImplementedException(); 
}

यह एक गैर-शून्य विधि है। यह है आदेश इंटरफ़ेस पूरा करने के लिए एक गैर शून्य विधि के लिए। लेकिन इस कार्यान्वयन को गैरकानूनी बनाने के लिए यह मूर्खतापूर्ण लगता है क्योंकि यह कुछ भी वापस नहीं करता है।

आपकी विधि के कारण एक अगम्य बिंदु है goto (याद रखें, एक while(true)लिखने के लिए एक और अधिक सुखद तरीका है goto) एक के बजाय throw(जो कि एक और रूप है goto) प्रासंगिक नहीं है।

संकलक भी कुछ वापस करने के बारे में चेतावनी क्यों नहीं देता है?

क्योंकि कंपाइलर के पास कोई अच्छा सबूत नहीं है कि कोड गलत है। किसी ने लिखा है while(true)और ऐसा लगता है कि जिस व्यक्ति ने ऐसा किया वह जानता था कि वे क्या कर रहे थे।

सी # में रीचैबिलिटी विश्लेषण के बारे में मैं और अधिक कहां पढ़ सकता हूं?

इस विषय पर मेरे लेख देखें:

ATBG: डी फैक्टो और डे जुरेबबिलिटी

और आप C # विनिर्देशन पढ़ने पर भी विचार कर सकते हैं।


तो क्यों यह कोड संकलित समय त्रुटि देता है: public int doNotReturnAnything() { boolean flag = true; while (flag) { //Do something } //no return } इस कोड में भी विराम बिंदु नहीं है। तो अब कैसे संकलक जानता है कि कोड गलत है।
संदीप पूनिया

@ संदीप पूनिया: आप यहां अन्य उत्तर पढ़ना चाहते हैं ... कंपाइलर केवल कुछ शर्तों का पता लगा सकता है।
डैनियल हिलगार्थ

9
@ संदीप पूनिया: बूलियन ध्वज को रनटाइम में बदला जा सकता है, क्योंकि यह एक कास्ट नहीं है, इसलिए लूप आवश्यक रूप से अनंत नहीं है।
श्मुली

9
@ संदीप पूनिया: सी # में स्पेसिफिकेशन कहता है कि if , while, for, switch, आदि, शाखाओं में निर्माणों कि पर काम स्थिरांक संकलक द्वारा बिना शर्त शाखाओं के रूप में माना जाता है। निरंतर अभिव्यक्ति की सटीक परिभाषा कल्पना में है। आपके प्रश्नों के उत्तर विनिर्देश में हैं; मेरी सलाह है कि आप इसे पढ़ें।
एरिक लिपर्ट

1
Every code path that returns must return a valueसबसे बढ़िया उत्तर। दोनों प्रश्नों को स्पष्ट रूप से संबोधित करता है। धन्यवाद
CPU1

38

जावा कंपाइलर अगम्य कोड ( whileलूप के बाद का कोड ) खोजने के लिए पर्याप्त स्मार्ट है

और उसके अगम्य के बाद से , वहाँ एक returnबयान जोड़ने का कोई मतलब नहीं है ( whileसमाप्त होने के बाद )

सशर्त साथ जाता है if

public int get() {
   if(someBoolean) {   
     return 10;
   }
   else {
     return 5;
   }
   // there is no need of say, return 11 here;
}

चूंकि बूलियन स्थिति someBooleanकेवल या तो मूल्यांकन कर सकती हैtrue याfalse , या इसके बाद return स्पष्ट रूप से प्रदान करने की आवश्यकता नहीं है if-else, क्योंकि यह कोड अनुपलब्ध है , और जावा इसके बारे में शिकायत नहीं करता है।


4
मुझे नहीं लगता कि यह वास्तव में इस सवाल का समाधान है। यह जवाब देता है कि आपको returnअगम्य कोड में एक बयान की आवश्यकता क्यों नहीं है , लेकिन ओपी के कोड में आपको किसी भी return वक्तव्य की आवश्यकता नहीं है ।
बोबसन

यदि जावा कंपाइलर अगम्य कोड (लूप के बाद का कोड) खोजने के लिए पर्याप्त स्मार्ट है, तो ये नीचे दिए गए कोड क्यों संकलित करते हैं, दोनों में अगम्य कोड है, लेकिन अगर विधि के साथ रिटर्न स्टेटमेंट की आवश्यकता होती है, लेकिन थोड़ी देर के साथ विधि नहीं होती है। public int doNotReturnAnything() { if(true){ System.exit(1); } return 11; } public int doNotReturnAnything() { while(true){ System.exit(1); } return 11;// Compiler error: unreachable code }
संदीप पूनिया

@ संदीपपूनिया: क्योंकि कंपाइलर को पता नहीं है कि System.exit(1)यह प्रोग्राम मार देगा। यह केवल कुछ प्रकार के अगम्य कोड का पता लगा सकता है।
डैनियल हिलगार्थ

@ डैनियल हिलगर्थ: ओके कंपाइलर नहीं जानता System.exit(1)कि प्रोग्राम को मार देगा, हम किसी का भी उपयोग कर सकते हैं return statement, अब कंपाइलर पहचानता है return statements। और व्यवहार समान है, वापसी की आवश्यकता है if conditionलेकिन इसके लिए नहीं while
संदीप पूनिया

1
एक विशेष मामले का उपयोग किए बिना अगम्य खंड का अच्छा प्रदर्शनwhile(true)
मैथ्यू

17

कंपाइलर जानता है कि whileलूप कभी भी निष्पादित करना बंद नहीं करेगा, इसलिए विधि कभी खत्म नहीं होगी, इसलिए एक returnबयान आवश्यक नहीं है।


13

यह देखते हुए कि आपका लूप एक स्थिर पर चल रहा है - संकलक जानता है कि यह एक अनंत लूप है - जिसका अर्थ है कि विधि कभी भी वापस नहीं आ सकती है।

यदि आप एक चर का उपयोग करते हैं - संकलक नियम लागू करेगा:

यह संकलन नहीं होगा:

// Define other methods and classes here
public int doNotReturnAnything() {
    var x = true;

    while(x == true) {
        //do something
    }
    //no return statement - won't compile
}

लेकिन क्या होगा अगर "कुछ करते हैं" किसी भी तरह से एक्स को संशोधित करना शामिल नहीं करता है .. कंपाइलर यह पता लगाने के लिए स्मार्ट नहीं है? चूतड़ :(
Lews थेरिन

नहीं - यह पसंद नहीं है।
दवे बिष्ट

@Lews यदि आपके पास कोई ऐसा तरीका है जिसे इंटिंग रिटर्न के रूप में चिह्नित किया गया है, लेकिन वास्तव में वापस नहीं आता है, तो आपको खुश होना चाहिए कि कंपाइलर इसे फ्लैग करता है, इसलिए आप इस विधि को शून्य के रूप में चिह्नित कर सकते हैं या इसे ठीक कर सकते हैं यदि आप इसके लिए इरादा नहीं रखते हैं व्यवहार।
मिकीफै

@ मायकेफ येप, विवादित नहीं।
लूइस थेरिन

1
मैं गलत हो सकता हूं लेकिन कुछ डिबगर चरों के संशोधन की अनुमति देते हैं। यहां जबकि x को कोड द्वारा संशोधित नहीं किया गया है और इसे JIT द्वारा अनुकूलित किया जाएगा, कोई भी x को गलत तरीके से संशोधित कर सकता है और विधि को कुछ वापस करना चाहिए (यदि ऐसी चीज को सी # डिबगर द्वारा अनुमति दी जाती है)।
मैकीज पीचोटका

11

जावा विनिर्देश नामक एक अवधारणा को परिभाषित करता है Unreachable statements। आपको अपने कोड में एक अप्राप्य विवरण रखने की अनुमति नहीं है (यह एक संकलन समय त्रुटि है)। आपको थोड़ी देर के बाद वापसी का विवरण देने की अनुमति नहीं है (सत्य); जावा में बयान। एक while(true);कथन निम्नलिखित कथनों को परिभाषा से अप्राप्य बनाता है, इसलिए आपको returnकथन की आवश्यकता नहीं है ।

ध्यान दें कि जब हॉल्टिंग समस्या जेनेरिक मामले में अवांछनीय है, तो अप्राप्य स्टेटमेंट की परिभाषा सिर्फ रुकने से ज्यादा सख्त है। यह बहुत ही विशिष्ट मामलों को तय कर रहा है जहां एक कार्यक्रम निश्चित रूप से रुकता नहीं है। संकलक सैद्धांतिक रूप से सभी अनंत छोरों और अगम्य बयानों का पता लगाने में सक्षम नहीं है, लेकिन इसे विनिर्देश में परिभाषित विशिष्ट मामलों का पता लगाना है (उदाहरण के लिए, while(true)मामला)


7

कंपाइलर स्मार्ट है यह पता लगाने के लिए कि आपका whileलूप अनंत है।

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

तो, आपके प्रश्न का उत्तर देने के लिए:

संकलक आपके कोड का विश्लेषण करता है और यह पता लगाने के बाद कि कोई निष्पादन पथ इसे ठीक से समाप्त होने वाले फ़ंक्शन के अंत तक गिरने की ओर नहीं ले जाता है।

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


7

प्रकार के सिद्धांत में, नीचे के प्रकार को कहा जाता है जो कि हर दूसरे प्रकार (!) का उपवर्ग है और इसका इस्तेमाल अन्य चीजों के बीच गैर-समाप्ति का संकेत देने के लिए किया जाता है। (अपवाद गैर-समाप्ति के एक प्रकार के रूप में गिना जा सकता है - आप सामान्य रास्ते से समाप्त नहीं होते हैं।)

तो एक सैद्धांतिक दृष्टिकोण से, गैर-समापन वाले ये कथन नीचे के प्रकार के कुछ वापस करने के लिए माना जा सकता है, जो कि int का एक उपप्रकार है, इसलिए आप एक प्रकार के दृष्टिकोण से सभी के बाद अपना रिटर्न मान प्राप्त करते हैं। और यह पूरी तरह से ठीक है कि इसका कोई मतलब नहीं है कि एक प्रकार इंट सहित अन्य सभी चीजों का एक उपवर्ग हो सकता है क्योंकि आप वास्तव में कभी भी वापस नहीं आते हैं।

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


6

ऐसी कोई स्थिति नहीं है जिसमें फ़ंक्शन एक उचित मूल्य वापस किए बिना अपने अंत तक पहुंच सकता है। इसलिए, कंपाइलर के पास शिकायत करने के लिए कुछ भी नहीं है।


5

विज़ुअल स्टूडियो में यह पता लगाने के लिए स्मार्ट इंजन है कि यदि आपने रिटर्न टाइप टाइप किया है, तो यह फ़ंक्शन / विधि के साथ रिटर्न स्टेटमेंट होना चाहिए।

PHP में के रूप में यदि आप कुछ भी नहीं लौटाया है तो आपका रिटर्न प्रकार सही है। संकलक 1 मिलता है अगर कुछ भी वापस नहीं आया है।

इस के रूप में

public int doNotReturnAnything() {
    while(true) {
        //do something
    }
    //no return statement
}

कंपाइलर जानता है कि बयान करते समय स्वयं में एक प्रकृति स्वभाव होता है इसलिए इस पर विचार नहीं करना चाहिए। और php संकलक स्वचालित रूप से सही हो जाएगा यदि आप अभिव्यक्ति की स्थिति में लिखते हैं।

लेकिन वीएस के मामले में यह आपको स्टैक में त्रुटि नहीं देगा।


4

आपका समय लूप हमेशा के लिए चलेगा और इसलिए बाहर नहीं आएगा; यह निष्पादित करना जारी रखेगा। इसलिए, जबकि {} का बाहरी भाग अप्राप्य है और रिटर्न लिखने या न लिखने का कोई मतलब नहीं है। कंपाइलर बुद्धिमान है यह पता लगाने के लिए कि कौन सा हिस्सा उपलब्ध है और कौन सा हिस्सा नहीं है।

उदाहरण:

public int xyz(){
    boolean x=true;

    while(x==true){
        // do something  
    }

    // no return statement
}

उपरोक्त कोड संकलित नहीं करेगा, क्योंकि ऐसा मामला हो सकता है कि लूप के शरीर के अंदर चर x का मान संशोधित किया गया हो। तो यह लूप पहुंच से बाहर का हिस्सा बनाता है! और इसलिए संकलक एक त्रुटि 'कोई विवरण नहीं मिला' को फेंक देगा।

कंपाइलर पर्याप्त बुद्धिमान नहीं है (या बल्कि आलसी;)) यह पता लगाने के लिए कि एक्स के मूल्य को संशोधित किया जाएगा या नहीं। आशा है कि यह सब कुछ साफ कर देगा।


7
यह वास्तव में इस मामले में है कि कंपाइलर के स्मार्ट होने का सवाल नहीं है। C # 2.0 में कंपाइलर यह जानने के लिए काफी स्मार्ट था कि int x = 1; while(x * 0 == 0) { ... }अनंत लूप है, लेकिन स्पेसिफिकेशन का कहना है कि लूप एक्सप्रेशन के स्थिर होने पर कंपाइलर को केवल कंट्रोल फ्लो की कटौती करनी चाहिए , और स्पेसिफिकेशन एक स्थिर अभिव्यक्ति को परिभाषित करता है जिसमें कोई वैरिएबल नहीं है । इसलिए कंपाइलर बहुत स्मार्ट था । C # 3 में मैंने कंपाइलर को स्पेसिफिकेशन से मैच किया, और तब से यह इस तरह के एक्सप्रेशन के बारे में जानबूझकर कम स्मार्ट है।
एरिक लिपर्ट

4

"कंपाइलर कुछ वापस करने के बारे में चेतावनी भी क्यों नहीं देता? या एक भाषा हमें एक अनौपचारिक लूप देने की अनुमति क्यों देती है जिसमें एक अनंत लूप होता है और कुछ भी नहीं लौटाता है?"।

यह कोड अन्य सभी भाषाओं में भी मान्य है (शायद हास्केल को छोड़कर!)। क्योंकि पहली धारणा यह है कि हम "जानबूझकर" कुछ कोड लिख रहे हैं।

और ऐसी परिस्थितियां हैं कि यह कोड पूरी तरह से मान्य हो सकता है जैसे कि आप इसे एक धागे के रूप में उपयोग करने जा रहे हैं; या यदि यह वापस आ रहा था Task<int>, तो आप लौटे इंट वैल्यू के आधार पर कुछ त्रुटि जाँच कर सकते हैं - जिसे वापस नहीं किया जाना चाहिए।


3

मैं गलत हो सकता हूं लेकिन कुछ डिबगर चरों के संशोधन की अनुमति देते हैं। यहां जबकि x को कोड द्वारा संशोधित नहीं किया गया है और इसे JIT द्वारा अनुकूलित किया जाएगा, कोई भी x को गलत तरीके से संशोधित कर सकता है और विधि को कुछ वापस करना चाहिए (यदि ऐसी चीज को सी # डिबगर द्वारा अनुमति दी जाती है)।


1

इसके लिए जावा केस की बारीकियां (जो शायद C # केस से बहुत मिलती-जुलती हैं) के साथ यह करना है कि कैसे जावा कंपाइलर यह निर्धारित करता है कि कोई विधि वापस आने में सक्षम है या नहीं।

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

यदि किसी विधि को रिटर्न प्रकार घोषित किया जाता है, तो कंपाइल-टाइम त्रुटि तब होती है जब विधि का शरीर सामान्य रूप से पूरा हो सकता है। दूसरे शब्दों में, रिटर्न प्रकार के साथ एक विधि को केवल रिटर्न स्टेटमेंट का उपयोग करके वापस लौटना चाहिए जो मूल्य वापसी प्रदान करता है; इसे "अपने शरीर के अंत को छोड़ने" की अनुमति नहीं है

संकलक यह देखना चाहता है कि क्या जेएलएस 14.21 अनुपलब्ध विवरणों में परिभाषित नियमों के आधार पर सामान्य समाप्ति संभव है क्योंकि यह सामान्य पूर्णता के नियमों को भी परिभाषित करता है।

उल्लेखनीय रूप से, अप्राप्य कथनों के नियम एक विशेष मामले को केवल उन छोरों के लिए बनाते हैं जिनकी एक परिभाषित trueस्थिर अभिव्यक्ति है:

एक बयान में सामान्य रूप से पूरा हो सकता है यदि निम्न में से कम से कम एक सच है:

  • जबकि कथन उपलब्ध है और मान अभिव्यक्ति के साथ स्थिति अभिव्यक्ति स्थिर अभिव्यक्ति (815.28) नहीं है।

  • एक पहुंच योग्य ब्रेक स्टेटमेंट है जो कि स्टेटमेंट से बाहर निकलता है।

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

इन नियमों का मतलब है कि whileएक स्थिर सच्ची अभिव्यक्ति और बिना किसी के साथ आपके कथन breakको कभी भी सामान्य रूप से पूरा करने के लिए नहीं माना जाता है , और इसलिए इसके नीचे किसी भी कोड को कभी भी पहुंच योग्य नहीं माना जाता है । विधि का अंत लूप के नीचे होता है, और चूंकि लूप के नीचे सब कुछ पहुंच से बाहर है, इसलिए विधि का अंत होता है, और इस प्रकार विधि संभवतः सामान्य रूप से पूरी नहीं हो सकती है (जो कि समान दिखती है)।

if दूसरी ओर, लूप्स को वहन करने वाले निरंतर अभिव्यक्तियों के बारे में विशेष छूट नहीं है।

की तुलना करें:

// I have a compiler error!
public boolean testReturn()
{
    final boolean condition = true;

    if (condition) return true;
}

साथ में:

// I compile just fine!
public boolean testReturn()
{
    final boolean condition = true;

    while (condition)
    {
        return true;
    }
}

भेद का कारण काफी दिलचस्प है, और सशर्त संकलन झंडे की अनुमति देने की इच्छा के कारण है जो कंपाइलर त्रुटियों (जेएलएस से) का कारण नहीं है:

यदि निम्नलिखित कथन को निम्नलिखित तरीके से संभाला जाए, तो कोई उम्मीद कर सकता है:

  • एक if-then स्टेटमेंट सामान्य रूप से iff को पूरा कर सकता है यदि निम्न में से कम से कम एक सत्य है:

    • यदि तत्कालीन कथन उपलब्ध है और स्थिति अभिव्यक्ति स्थिर अभिव्यक्ति नहीं है जिसका मूल्य सत्य है।

    • तत्कालीन कथन सामान्य रूप से पूरा हो सकता है।

    तत्कालीन कथन पुन: प्राप्य है यदि if-तत्कालीन कथन उपलब्ध है और स्थिति अभिव्यक्ति स्थिर अभिव्यक्ति नहीं है जिसका मान गलत है।

  • एक if-then-else स्टेटमेंट सामान्य रूप से पूरा कर सकता है iff- स्टेटमेंट सामान्य रूप से पूरा कर सकता है या अन्य स्टेटमेंट सामान्य रूप से पूरा कर सकता है।

    • तत्कालीन कथन पुन: प्राप्य है यदि if-if-अन्यथा कथन उपलब्ध है और स्थिति अभिव्यक्ति स्थिर अभिव्यक्ति नहीं है जिसका मान गलत है।

    • इफ-स्टेटमेंट इफ-वाचिंग इफ-इफ-इफ-इयर्न स्टेटमेंट उपलब्ध है और कंडीशन एक्सप्रेशन एक स्थिर एक्सप्रेशन नहीं है जिसका मान सत्य है

यह दृष्टिकोण अन्य नियंत्रण संरचनाओं के उपचार के अनुरूप होगा। हालाँकि, यदि कथन को "सशर्त संकलन" उद्देश्यों के लिए सुविधाजनक रूप से उपयोग करने की अनुमति देने के लिए, वास्तविक नियम भिन्न हैं।

एक उदाहरण के रूप में, निम्नलिखित कथन एक संकलन-समय त्रुटि का परिणाम देता है:

while (false) { x=3; }क्योंकि कथन उपलब्ध x=3;नहीं है; लेकिन सतही रूप से समान मामला:

if (false) { x=3; }संकलन-समय त्रुटि में परिणाम नहीं करता है। एक अनुकूलन करने वाले कंपाइलर को यह महसूस हो सकता है कि स्टेटमेंट x=3;कभी निष्पादित नहीं होगा और उत्पन्न क्लास फाइल से उस स्टेटमेंट के लिए कोड को छोड़ना चुन सकता है, लेकिन स्टेटमेंटx=3; यहाँ निर्दिष्ट तकनीकी अर्थों में को "अगम्य" नहीं माना जाता है।

इस भिन्न उपचार का औचित्य प्रोग्रामर्स को "ध्वज चर" को परिभाषित करने की अनुमति देना है:

static final boolean DEBUG = false; और फिर कोड लिखें जैसे:

if (DEBUG) { x=3; } विचार यह है कि DEBUG के मूल्य को असत्य से सत्य में या असत्य से असत्य में बदलना संभव है और फिर कोड को प्रोग्राम टेक्स्ट में कोई अन्य परिवर्तन न करके सही ढंग से संकलित करना चाहिए।

एक संकलक त्रुटि के कारण सशर्त ब्रेक स्टेटमेंट क्यों होता है?

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

यदि breakपहुंच योग्य है, तो लूप के बाद का कोड एक बार फिर से पहुंच योग्य माना जाता है। चूंकि कोई भी पहुंच योग्य कोड नहीं है जिसके परिणामस्वरूप लूप के बाद अचानक समाप्ति होती है, फिर विधि को सामान्य रूप से पूरा करने में सक्षम माना जाता है, और इसलिए संकलक इसे एक त्रुटि के रूप में चिह्नित करता है।

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