उनमें से कोई भी संकलित होना चाहिए। सी # विनिर्देश के लिए एक स्विच खंड में कम से कम एक कथन है। पार्सर इसे अस्वीकार कर देना चाहिए।
चलिए इस तथ्य को अनदेखा करते हैं कि पार्सर खाली कथन सूची की अनुमति देता है; यह प्रासंगिक नहीं है। विनिर्देश कहता है कि स्विच खंड के अंत में एक पहुंच योग्य अंत बिंदु नहीं होना चाहिए; यह प्रासंगिक बिट है।
void M(int x) { switch(2) { case 2: ; } }
तो यह एक त्रुटि होना चाहिए:
अपने पिछले उदाहरण में, स्विच खंड एक से पहुंचा जा सकता अंत बिंदु है।
यदि आप था:
void M(int x) { switch(x) { case 2: ; } }
तो संकलक अगर एक्स कभी 2. हो जाएगा यह परंपरागत ढंग से मान लिया गया है कि यह कर सकते थे, और कहता है कि खंड एक से पहुंचा जा सकता अंत बिंदु है पता नहीं है, क्योंकि स्विच मामले लेबल पहुंच योग्य है।
यदि आप
void M(int x) { switch(1) { case 2: ; } }
था तब संकलक कारण सकता है कि अंत बिंदु पहुंच योग्य नहीं है क्योंकि मामला लेबल पहुंच योग्य नहीं है। संकलक जानता है कि लगातार 1 यदि आप था निरंतर 2.
के बराबर नहीं है:
void M(int x) { switch(x = 1) { case 2: ; } }
या
void M(int x) { x = 1; switch(x) { case 2: ; } }
तो आप जानते हैं और मुझे पता है कि अंत बिंदु नहीं है पहुंचने योग्य, लेकिन संकलक उसे नहीं जानता है। विनिर्देशन में नियम यह है कि पहुंच क्षमता केवल निरंतर अभिव्यक्तियों का विश्लेषण करके निर्धारित की जाती है। कोई भी अभिव्यक्ति जिसमें एक चर शामिल है, भले ही आप किसी अन्य माध्यम से अपना मान जानते हों, निरंतर अभिव्यक्ति नहीं है।
अतीत में सी # कंपाइलर में ऐसी चीजें थीं जहां यह मामला नहीं था। आप जैसी चीजों कह सकते हैं:
void M(int x) { switch(x * 0) { case 2: ; } }
और संकलक कारण होता है कि एक्स * 0 0 होना ही था, इसलिए मामले लेबल पहुंच योग्य नहीं है। वह एक बग था, जिसे मैंने सी # 3.0 में तय किया था। विनिर्देश कहता है कि केवल स्थिरांक का उपयोग उस विश्लेषण के लिए किया जाता है, और x
एक चर है, स्थिर नहीं है।
अब, यदि प्रोग्राम कानूनी है तो संकलक इस तरह की उन्नत तकनीकों का उपयोग कर सकते हैं ताकि कोड उत्पन्न हो सके। आप कहते हैं कि कुछ की तरह हैं:
void M(int x) { if (x * 0 == 0) Y(); }
फिर संकलक है जैसे कि आप
void M(int x) { Y(); }
लिखा था अगर यह चाहता कोड उत्पन्न कर सकते हैं।लेकिन यह इस तथ्य का उपयोग नहीं कर सकता कि x * 0 == 0
कथन पहुंचने के उद्देश्य के लिए सच है।
अंत में, यदि आप
void M(int x) { if (false) switch(x) { case 2: ; } }
तो हम जानते हैं कि स्विच पहुंच योग्य नहीं है, इसलिए ब्लॉक एक ही पहुंचा जा सकता अंत बिंदु नहीं है, तो यह है, आश्चर्यजनक रूप से, कानूनी। लेकिन उपरोक्त चर्चा दिया, अब आप जानते हैं कि
void M(int x) { if (x * 0 != 0) switch(x) { case 2: ; } }
false
रूप x * 0 != 0
का इलाज नहीं है, इसलिए अंत बिंदु पहुंच योग्य माना जाता है।
यह संभव है कि संकलक पहले को अनुकूलित कर सके, लेकिन असाइनमेंट के कारण दूसरे को हटा नहीं सकता है। –
मेरा अनुमान है कि '1' एक स्थिर अभिव्यक्ति है जिसे संकलन समय पर जाना जाता है, जिससे संकलक पूरे स्विच को अनुकूलित कर देता है, जबकि 'i = 1' एक गैर-निरंतर अभिव्यक्ति है (यद्यपि संकलक को विशिष्ट मान उत्पन्न करने के लिए भी जाना जाता है) तो संकलक स्विच रखने की कोशिश करता है। – dasblinkenlight
एक आदर्श दुनिया में, संकलक शायद इन दोनों को स्वीकार या अस्वीकार कर देना चाहिए। यह निश्चित रूप से उनके लिए कोई कोड उत्पन्न नहीं करना चाहिए। लेकिन इस दुनिया में, मुझे लगता है कि यह "फोरेस्ट गंप प्रभाव:" का एक और उदाहरण है: बेवकूफ बेवकूफ है ":) प्रश्न: समय/मस्तिष्क को बर्बाद क्यों करते हैं? – paulsm4