2012-03-29 13 views
5

सीपीपी में, निम्न कोड स्निपेट का परिणाम है: 5 5 5 लेकिन जावा में, उसी कोड स्निपेट का परिणाम है: 3 5 7 मुझे नहीं पता कि, क्या कोई इसे समझा सकता है? बहुत बहुत धन्यवाद!अभिव्यक्ति प्राथमिकता? यह परिणाम कैसे होता है?

class H 
{ 
    public: 
    H &pr (int n, char * prompt) 
    { 
     cout<<prompt<<n<<" "; 
     return *this; 
    } 

    H &fn(int n) 
    { 
     return pr(n,""); 
    } 
}; 

void test() 
{ 
    int v=3; 
    H h; 
    h.fn(v).fn(v=5).fn((v=7)); 
} 
+2

संक्षिप्त उत्तर "सी ++ जावा नहीं है।" –

+0

बीटीडब्लू, मुझे ऐसे प्रश्न पसंद हैं जो मुझे कुछ डिस्सेप्लर को बाहर निकालने दें। :) –

उत्तर

6

में सीपीपी, निम्नलिखित कोड स्निपेट का परिणाम है: 5 5 5 लेकिन जावा में, उसी कोड स्निपेट का परिणाम है: 3 5 7 मुझे नहीं पता क्यों,

क्योंकि सी ++ जावा नहीं है :)

आप पिछले दो फ़ंक्शन कॉल में वेरिएबल v को म्यूट कर रहे हैं। के dissassembly पर नजर डालते हैं (यहाँ डिबग बातें अधिक स्पष्ट रूप से देखने के लिए, रिलीज में 5 की एक स्थिर मान प्रयोग किया जाता है, लेकिन यह भी 7 बस के रूप में आसानी से हो सकता है क्यों आप देखेंगे।):

h.fn(v).fn(v=5).fn((v=7)); 
00411565 mov   dword ptr [v],7 
0041156C mov   dword ptr [v],5 
00411573 mov   eax,dword ptr [v] 
00411576 push  eax 

आदेश अभिव्यक्ति मूल्यांकन का ऑर्डर होने की गारंटी नहीं है जिसे आप यहां फ़ंक्शंस कहते हैं। आप को sequence points के बीच संशोधित कर रहे हैं। 7v को सौंपा गया, फिर 5, तो पहला फ़ंक्शन कहा जाता है। ध्यान दें कि उस क्रम में 7 और फिर 5 होना आवश्यक नहीं है, इसे बदला जा सकता है! मूल्यांकन का आदेश अनिर्दिष्ट है, यह कुछ भी हो सकता है।

आपके पास फ़ंक्शन की एक श्रृंखला है जो v को दो बार बदलती है। आप इस तथ्य पर भरोसा नहीं कर सकते कि प्रत्येक उत्परिवर्तन आपके द्वारा यहां टाइप किए गए क्रम में होगा।

हम इसे सरल बना सकते हैं। मान लें कि हमारे पास दो कार्य हैं; x और y कि दोनों int लौटाते हैं। अगर मैं लिखना:

int k = x() + y(); 

कोई गारंटी नहीं कि x()y() से पहले बुलाया जाएगा नहीं है। इसलिए, यदि आप दोनों कार्यों के लिए एक तर्क को म्यूट कर रहे हैं तो उत्परिवर्तन कॉल में y() पर हो सकता है, जो आप देख रहे हैं।

+1

+1 इसे थोड़ा और स्पष्ट बनाने के लिए: प्रोग्राम ने मानक द्वारा * अनिर्धारित व्यवहार * किया है, और इसका मतलब है कि प्रोग्राम मूल रूप से निम्न में से किसी भी आउटपुट का उत्पादन कर सकता है: 3 5 6; 3 5 5; 3 7 7; 5 5 5; 5 5 7; 5 7 7; 7 7 7 (और संभवतः अन्य जो मैंने बीच में छोड़ा) –

+0

मुझे यह मिल गया है, बहुत बहुत धन्यवाद। – newda

2

समस्या यह है कि मानक गारंटी नहीं देता है कि अभिव्यक्तियों का मूल्यांकन कैसे किया जाता है।

ओह अच्छा, यह आंशिक रूप से करता है, लेकिन अगर आप उस कोड को संकलित आप एक विशिष्ट चेतावनी कहा गया है कि

warning: operation on ‘v’ may be undefined 

मुझे लगता है कि इस सवाल का इस मुद्दे के बारे में आप प्रबुद्ध कर सकते हैं: Is this code well-defined?

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