2015-07-03 5 views
53

मानक राज्यों को स्विच करने के संबंध में निम्नलिखित हैं। "जब स्विच स्टेटमेंट निष्पादित किया जाता है, तो उसकी स्थिति का मूल्यांकन किया जाता है और प्रत्येक मामले निरंतर तुलना की जाती है।"सी ++ स्विच स्टेटमेंट अभिव्यक्ति मूल्यांकन गारंटी

क्या इसका मतलब यह है कि हालत अभिव्यक्ति केवल एक बार और एक बार मूल्यांकन की जाती है, और प्रत्येक कंपाइलर के लिए मानक द्वारा इसकी गारंटी दी जाती है?

उदाहरण के लिए, जब एक साइड इफेक्ट के साथ स्विच स्टेटमेंट हेड में फ़ंक्शन का उपयोग किया जाता है।

int f() { ... } 
switch (f()) 
{ 
    case ...; 
    case ...; 
} 
+10

यह पूछने की तरह है कि 'int main() {putchar (' c '); } 'केवल एक बार 'पुचर' को कॉल करने की गारंटी है (और इस प्रकार केवल एक 'सी' मुद्रित करने की गारंटी है)। वास्तव में, मुझे मानक में किसी भी पाठ से अवगत नहीं है जो ऐसी गारंटी प्रदान करता है। – cpplearner

+9

मैं असहमत हूं। स्विच एक विशेष बयान है, जिसे असेंबली में कई प्रभावी तरीकों से लागू किया जा सकता है। मेरे लिए यह स्पष्ट नहीं है। – mikk

+5

मुझे लगता है कि cpplearner सही है, 'असेंबली में कई प्रभावी तरीके "को' as-if 'नियम के तहत अनुमति है।इसके अलावा गारंटी है कि आपके फ़ंक्शन कॉल (जिनके साइड इफेक्ट्स हैं) का मूल्यांकन एक बार किया जाता है, * प्रत्येक संदर्भ में * सी ++ में, वही है, यह किस तरह का संदर्भ है, इस बारे में अपरिहार्य है। – ybungalobill

उत्तर

36

मुझे लगता है कि यह गारंटी है कि f केवल एक बार बुलाया जाता है।

पहले हम

हालत अभिन्न प्रकार, गणन प्रकार, या वर्ग प्रकार की होगी।

[6.4.2 (1)] (गैर अभिन्न सामग्री यहां लागू नहीं होता है), और

एक शर्त एक अभिव्यक्ति है कि का मूल्य अभिव्यक्ति

का मूल्य है

[6.4 (4)]। इसके अलावा,

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

[6.4 (4)] हमारे मामले में इसका मतलब है कि, "हालत" बस प्रकार int, नहीं f की एक सादे मूल्य है। f केवल स्थिति के लिए मूल्य खोजने के लिए प्रयोग किया जाता है।अब जब नियंत्रण switch बयान

इसकी हालत मूल्यांकन किया जाता है पहुँचता है

[6.4.2 (5)], यानी हम int है कि हमारे "हालत" के रूप में f द्वारा दिया जाता है के मूल्य का उपयोग । फिर अंत में हालत (किस प्रकार int, नहीं f के एक मूल्य है),

प्रत्येक मामले निरंतर के साथ तुलना में है

[6.4.2 (5)]। यह f से साइड इफेक्ट्स को फिर से ट्रिगर नहीं करेगा।

N3797 से सभी उद्धरण। (एन 4140 भी चेक किया गया, कोई अंतर नहीं)

+0

N3797 एक मध्यवर्ती मसौदा है, सी ++ 14 के लिए एन 4139/एन 4140, या सी ++ 11 –

+9

@MattMcNabb के लिए N3337 का उपयोग करने पर विचार करें क्या वे मुफ्त में उपलब्ध हैं? (और इस सवाल के लिए, क्या वे अलग हैं?) –

+2

मुझे लगता है कि ओपी की अस्पष्टता वाक्य की पार्सिंग से उत्पन्न होती है क्योंकि इसकी स्थिति का मूल्यांकन किया जाता है (और प्रत्येक मामले निरंतर तुलना में) 'या '(इसकी स्थिति का मूल्यांकन और तुलना की जाती है) के साथ) प्रत्येक मामले स्थिर 'जो स्थिति के टाइपिंग के साथ कुछ भी नहीं है। – pqnet

2

धारा 6.4.4:

... एक शर्त एक अभिव्यक्ति है कि का मूल्य अभिव्यक्ति के मूल्य, प्रासंगिक रूप स्विच के अलावा अन्य बयानों के लिए bool में बदला है ;. हालत का ..the मूल्य के रूप में बस "हालत" जहां उपयोग स्पष्ट

मेरी समझ में है करने के लिए भेजा जाएगा, बोली ऊपर टी के बराबर है छद्म कोड निम्नलिखित वह:

switchCondition := evaluate(expression) 

अब आप अपने उद्धरण

जोड़ने ... इसकी हालत का मूल्यांकन किया और प्रत्येक मामले लगातार साथ तुलना में है।

कौन सा करने के लिए अनुवाद किया जाना चाहिए:

foreach case in cases 
    if case.constant == switchCondition 
     goto case.block 

तो, हाँ, ऐसा लगता है कि यह मामला है।

0

अभिव्यक्ति की गारंटी है कि नियंत्रण के प्रवाह द्वारा केवल एक बार मूल्यांकन किया जाता है। यह मानक N4431 §6.4.2/6 स्विच बयान [stmt.switch] (जोर मेरा) में उचित है:

अपने आप में

मामले और डिफ़ॉल्ट लेबल के प्रवाह को परिवर्तित न करें नियंत्रण, जो इस तरह के लेबल में unimpeded जारी है। स्विच से बाहर निकलने के लिए, ब्रेक देखें, 6.6.1। [नोट: आमतौर पर, प्रतिस्थापन स्विच का विषय यौगिक है और केस और डिफ़ॉल्ट लेबल (कंपाउंड) सबस्टेटमेंट के भीतर निहित शीर्ष-स्तरीय बयानों पर दिखाई देते हैं, लेकिन इसकी आवश्यकता नहीं है। घोषणाएं स्विच-स्टेटमेंट के सबस्टेटमेंट में दिखाई दे सकती हैं। - अंत टिप्पणी]

+4

मुझे लगता है कि यह उद्धरण केवल अंतर्निहित गिरावट को परिभाषित करता है। –

+1

@ बाममितयुगेन आईएमएचओ मानक से उपर्युक्त उद्धरण स्पष्ट रूप से एक स्पष्ट औचित्य देता है कि स्थिति का मूल्यांकन केवल एक बार किया जाएगा क्योंकि अन्यथा प्रवाह नियंत्रण का उल्लंघन किया जाएगा। – 101010

3

हाँ अभिव्यक्ति केवल एक बार जब स्विच बयान निष्पादित किया जाता है मूल्यांकन किया जाता है:

§ 6.4 चयन बयान

4 [...] एक का मान शर्त जो कि अभिव्यक्ति है अभिव्यक्ति का मान है [...] स्थिति का मूल्य केवल "स्थिति" के रूप में संदर्भित किया जाएगा जहां उपयोग स्पष्ट नहीं है।

इसका मतलब है कि अभिव्यक्ति मूल्यांकन किया जाता है और इसके मूल्य condition प्रत्येक case बयान के खिलाफ मूल्यांकन किया जाना माना जाता है।

2

क्या यह कोड hello एक या दो बार प्रिंट करता है?

int main() { 
    printf("hello\n"); 
} 

ठीक है, मुझे लगता है कि इस सवाल का जवाब क्या मानक बजाय विशिष्ट switch बयान शब्दों की तुलना में वर्णन करता है की अधिक सामान्य समझ में है।

कार्यक्रम निष्पादन [परिचय।निष्पादन] मानक कुछ अमूर्त मशीन के व्यवहार का वर्णन करता है जो निष्पादित करता है जो प्रोग्राम C++ व्याकरण के अनुसार पार्स किया गया है। यह वास्तव में परिभाषित नहीं करता है कि 'सार मशीन' या 'निष्पादित' का अर्थ क्या है, लेकिन उनका मतलब उनके स्पष्ट कंप्यूटर विज्ञान अवधारणाओं, यानी एक कंप्यूटर है जो अमूर्त वाक्यविन्यास पेड़ से गुजरता है और इसके द्वारा वर्णित अर्थशास्त्र के अनुसार इसके प्रत्येक भाग का मूल्यांकन करता है मानक। इसका तात्पर्य है कि यदि आपने एक बार कुछ लिखा है, तो निष्पादन उस बिंदु पर पहुंच जाता है, तो इसका मूल्यांकन केवल एक बार किया जाता है।

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

5

पढ़ना N4296

10 पृष्ठ पैरा 14:

एक पूर्ण अभिव्यक्ति के साथ जुड़े हर मूल्य गणना और पक्ष प्रभाव हर मूल्य गणना और पक्ष अगले पूर्ण अभिव्यक्ति के साथ जुड़े प्रभाव से पहले अनुक्रम है मूल्यांकन के लिए।

जब मैं पैरा की पहली पंक्ति पढ़ता हूं। 10 (उस से ऊपर):

एक पूर्ण अभिव्यक्ति एक अभिव्यक्ति है जो की एक अन्य अभिव्यक्ति नहीं है।

मुझे विश्वास है कि एक switch बयान की हालत एक पूर्ण अभिव्यक्ति है और प्रत्येक शर्त अभिव्यक्ति (निष्पादन पर तुच्छ यद्यपि) एक पूर्ण अभिव्यक्ति है।

switch एक बयान एक अभिव्यक्ति नहीं है (6.4.2 और कई अन्य स्थानों को देखें)।

तो switch के मूल्यांकन को पढ़कर case स्थिरांक के मूल्यांकन से पहले होना चाहिए।

जैसा कि कई अंक स्पष्ट निष्कर्ष पर आने के लिए विनिर्देश के कष्टप्रद पढ़ने के लिए उबालते हैं।

मैं उस वाक्य मैं निम्नलिखित संशोधन (बोल्ड में) का प्रस्ताव होगा की समीक्षा की सहकर्मी हैं:

जब स्विच बयान निष्पादित किया जाता है, इसकी हालत एक बार प्रति स्विच बयान के निष्पादन मूल्यांकन किया जाता है और प्रत्येक मामले निरंतर तुलना की तुलना में।

+0

आप क्यों मानते हैं कि स्विच कथन में नियंत्रण अभिव्यक्ति पूर्ण अभिव्यक्ति नहीं है? स्पष्ट रूप से यह एक अभिव्यक्ति है, तो आपको लगता है कि यह किस बड़ी अभिव्यक्ति का हिस्सा है? –

+0

@BenVoigt मुझे विश्वास नहीं है कि यह आपके द्वारा दिए गए कारणों के लिए पूर्ण अभिव्यक्ति नहीं है। मैंने अपनी सजा संपादित की है। उम्मीद है कि यह स्पष्ट बनाता है। – Persixty

+2

यदि आप दोहरे नकारात्मक से बचने के लिए पुन: प्रयास कर सकते हैं तो इससे मदद मिलेगी (विशेष रूप से क्योंकि दोनों भाग अलग हैं जैसे वे हैं)। –

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