2011-11-28 15 views
8
int& foo() { 
    printf("Foo\n"); 
    static int a; 
    return a; 
} 

int bar() { 
    printf("Bar\n"); 
    return 1; 
} 

void main() { 
    foo() = bar(); 
} 

मुझे यकीन नहीं है कि पहले किस का मूल्यांकन किया जाना चाहिए।असाइनमेंट ऑपरेटर में सी ++ फ़ंक्शन मूल्यांकन ऑर्डर

मैंने वीसी में कोशिश की है कि बार फ़ंक्शन पहले निष्पादित किया गया है। हालांकि, जी ++ (फ्रीबीएसडी) द्वारा कंपाइलर में, यह पहले फू फ़ंक्शन का मूल्यांकन करता है।

बहुत दिलचस्प सवाल इसके बाद के संस्करण समस्या से ली गई है, मैं एक गतिशील सरणी (std :: वेक्टर) मान लीजिए

std::vector<int> vec; 

int foobar() { 
    vec.resize(vec.size() + 1); 
    return vec.size(); 
} 

void main() { 
    vec.resize(2); 
    vec[0] = foobar(); 
} 

पिछले परिणाम के आधार पर, कुलपति foobar() का मूल्यांकन करता है और उसके बाद वेक्टर प्रदर्शन ऑपरेटर[]। इस तरह के मामले में कोई समस्या नहीं है। हालांकि, जीसीसी के लिए, क्योंकि वीसी [0] का मूल्यांकन किया जा रहा है और foobar() फ़ंक्शन सरणी के आंतरिक सूचक को बदल सकता है। Foobar() के निष्पादन के बाद vec [0] को अमान्य किया जा सकता है।

यह मतलब है कि हम कोड ऐसी है कि मूल्यांकन के

void main() { 
    vec.resize(2); 
    int a = foobar(); 
    vec[0] = a; 
} 
+3

+2, यह एक दिलचस्प सवाल है; यह ऐसा कुछ है जिसे मैंने कभी नहीं माना है। जाहिर है आप परेशानी में हैं यदि आप वैसे भी कोड का उपयोग करना शुरू करते हैं :) –

+0

+1। यह वास्तव में एक दिलचस्प सवाल है; उससे अधिक सवाल बहुत अच्छी तरह से पूछा जाता है। एक अच्छी तरह से लिखा प्रश्न। – Nawaz

+1

मैं आज के एक दिलचस्प उदाहरण में आया: 'auto_ptr पी (नया int); smart_map मीटर; एम [1] = पी। कृपया(); 'यदि आपको लगता है कि' smart_map :: ऑपरेटर [] 'फेंक सकता है, तो आपके पास ऐसा मामला हो सकता है जहां' auto_ptr' अपना स्वामित्व जारी करता है लेकिन मानचित्र कभी स्वामित्व ग्रहण नहीं करता है, मामला जहां एलएचएस से पहले आरएचएस का मूल्यांकन किया जाता है। (मान लीजिए कि 'smart_map' एक एसटीएल 'मैप' की तरह है, सिवाय इसके कि यह विनाश पर प्रत्येक कुंजी/मूल्य जोड़ी के सूचक मूल्य को हटा देता है।) – mrkj

उत्तर

8

आदेश उस मामले में अनिर्दिष्ट होगा अलग करने के लिए की जरूरत है। इस तरह के कोड लिखने

इसी प्रकार के उदाहरण here

0

एक अभिव्यक्ति के मूल्यांकन के आदेश न अनिर्दिष्ट व्यवहार है।
यह संकलक पर निर्भर करता है जिस पर यह मूल्यांकन करने का विकल्प चुनता है।

आपको शच कोड लिखने से बचना चाहिए।
हालांकि यदि कोई दुष्प्रभाव नहीं है तो आदेश से कोई फर्क नहीं पड़ता।

आदेश मामलों, तो अपने कोड गलत है/नहीं पोर्टेबल/अलग परिणाम विभिन्न compilers करवाते हैं ** दे सकता है।

5

सी ++ में अवधारणा जो नियंत्रित करती है कि मूल्यांकन के आदेश को परिभाषित किया गया है उसे sequence point कहा जाता है।

असल में, एक अनुक्रम बिंदु पर, यह गारंटी है कि उस बिंदु से पहले सभी अभिव्यक्तियों (अवलोकन योग्य दुष्प्रभावों के साथ) का मूल्यांकन किया गया है, और उस बिंदु से परे कोई अभिव्यक्ति अभी तक मूल्यांकन नहीं किया गया है।

हालांकि कुछ इसे आश्चर्यचकित कर सकते हैं, असाइनमेंट ऑपरेटर अनुक्रम बिंदु नहीं है। सभी अनुक्रम बिंदुओं की एक पूरी सूची Wikipedia article में है।

+2

... _was_ अनुक्रम बिंदु कहा जाता है। इस वर्ष के बाद से, हम _sequenced__ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ – MSalters

+0

@MSalters: इसे इंगित करने के लिए धन्यवाद - पता नहीं था! –

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