2010-09-03 13 views
17

ठीक है, मैं एक छोटे से इस सवाल पूछने के लिए शर्मिंदा हूँ, लेकिन मैं सिर्फ यह सुनिश्चित होना चाहते हैं ...शॉर्ट सर्किट मूल्यांकन और साइड इफेक्ट

यह ज्ञात है कि सी बूलियन भाव में शॉर्ट सर्किट मूल्यांकन का उपयोग करता है:

int c = 0; 
if (c && func(c)) { /* whatever... */ } 

कि उदाहरण func(c) में नहीं बुलाया क्योंकि c0 का आकलन करती है। लेकिन अधिक परिष्कृत उदाहरण के बारे में, जहां तुलना के साइड इफेक्ट्स की तुलना में परिवर्तनीय की तुलना में बदल जाएगी?

int c; /* this is not even initialized... */ 
if (canInitWithSomeValue(&c) && c == SOMETHING) { /*...*/ } 

समारोह canInitWithSomeValue रिटर्न सच और सफलता के मामले में दिए गए सूचक पर परिवर्तन मूल्य: इस तरह। क्या यह गारंटी है कि इस उदाहरण में बाद की तुलना (c == SOMETHING) canInitWithSomeValue(&c) द्वारा मान सेट का उपयोग करती है?

कोई फर्क नहीं पड़ता कि संकलक कितने भारी अनुकूलन का उपयोग करता है?

+0

मुझे लगता है कि आप शॉर्ट सर्किट मूल्यांकन और संकलक अनुकूलन को भ्रमित कर सकते हैं। पहले उदाहरण में, संकलक उस पूरे 'if' कथन को ऑप्टिमाइज़ कर देगा, क्योंकि यह कभी नहीं चला सकता है। शॉर्ट सर्किट-मूल्यांकन का अर्थ यह होगा कि यदि आपके पास 'if (func1() && func2()) {...}', और func1() को रनटाइम ** पर झूठी ** का मूल्यांकन किया गया था (यानी संकलन करते समय निश्चित रूप से नहीं), तो कोड को 'func2() 'की जांच नहीं करनी चाहिए - कंपाइलर को मशीन कोड तैयार करना चाहिए था कि अगर' func1() 'गलत है, तो' func2() 'नहीं कहा जाता है। – Stephen

+0

कि 'int c = 0' यह इंगित करने के लिए था कि' सी' तुलना के समय '0' के बराबर है, मुझे एहसास है कि एक ऐसे मामले में जो संकलक सरल 'if' को अनुकूलित करेगा। –

+0

आह, मैं क्षमा चाहता हूं। मैंने आपको गलत समझा मैं क्षमाप्रार्थी हूं। – Stephen

उत्तर

23

यह गारंटी है कि बाद में की तुलना (इस उदाहरण में ग == कुछ) मूल्य canInitWithSomeValue (& ग) द्वारा निर्धारित का उपयोग करता है है?

हां। क्योंकि वहाँ एक sequence point

&& (तार्किक और) के बाएँ और दाएँ ऑपरेंड, || (तार्किक या), और अल्पविराम ऑपरेटरों के मूल्यांकन के बीच

है। उदाहरण के लिए, *p++ != 0 && *q++ != 0 अभिव्यक्ति में, उप-अभिव्यक्ति * p ++! = 0 के सभी दुष्प्रभाव q तक पहुंचने के किसी भी प्रयास से पहले पूरा हो गए हैं।


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

+0

महान उत्तर, धन्यवाद! –

5

हां। क्योंकि && और || ऑपरेटर दोनों को अनुक्रम बिंदु भी कहा जाता है। उत्तरार्द्ध परिभाषित करता है जब पिछले ऑपरेशन के दुष्प्रभावों को पूरा किया जाना चाहिए और अगले में से शुरू नहीं होना चाहिए था।

1

अगर स्टेटमेंट समग्र स्थिति के भीतर मूल्यांकन सख्ती से दाएं को छोड़ दिया गया है। एकमात्र परिस्थिति जिसके अंतर्गत आपके दूसरे परीक्षण को ऑप्टिमाइज़ किया जाएगा, यदि संकलक 100% निश्चितता के साथ निर्धारित कर सकता है कि पहला समान रूप से झूठ के बराबर है।

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