2012-06-16 12 views
5

जब मैं यह कोड चलाता हूं, आउटपुट 11, 10.फ़ंक्शन तर्कों में पोस्ट-वृद्धि का उपयोग

पृथ्वी पर ऐसा क्यों होगा? क्या कोई मुझे इस बारे में स्पष्टीकरण दे सकता है जो मुझे उम्मीद से उजागर करेगा?

धन्यवाद

#include <iostream> 
using namespace std; 

void print(int x, int y) 
{ 
    cout << x << endl; 
    cout << y << endl; 
} 
int main() 
{ 
    int x = 10; 
    print(x, x++); 
} 
+1

मैं एक बहुत ही ध्यान देने योग्य त्रुटि/जीसीसी 4.7.0 पर चेतावनी (-Werror) पाने पर 'एक्स' अपरिभाषित किया जा सकता है आपरेशन [-Werror = अनुक्रम सूत्री] '। आपका चेतावनी स्तर चालू होना हमेशा अच्छा होता है। – chris

+0

@ acidzombie24, मुझे लगता है कि आपने मेरी पोस्ट संपादित की है, खासकर प्रिंट के फ़ंक्शन पैरामीटर। इसके लिए क्या कारण था? "X ++" से "x + 1" प्रकार के दूसरे पैरामीटर को पूरे पोस्ट के उद्देश्य को हरा देता है, है ना? – ordinary

+0

ओह क्षमा करें। यह एक बड़ी निगरानी थी। मैं कुछ कोड के साथ खेल रहा था और मैं भूल गया कि मैंने ++ को +1 में बदल दिया है। संख्याओं और प्रारूपों से मुझे परेशान किया गया और मैंने इसके बारे में अपना कोड कॉपी/पेस्ट किया। +1 के साथ एक ... ओह। मैंने इसे वापस बदल दिया। (मुझे आशा है कि आप अपनी खुद की पोस्ट को संपादित करने में सक्षम हैं ताकि आप ऐसा कर सकें यदि आप फिर से ऐसी गलती देखते हैं) –

उत्तर

11

C++ standard राज्यों (अनुभाग 1.9.16 में एक नोट):

Value computations and side effects associated with the different argument expressions are unsequenced.

दूसरे शब्दों में, यह है अपरिभाषित और/या संकलक पर निर्भर जो आदेश तर्क में मूल्यांकन किया जाता से पहले उनके मूल्य में पारित हो जाता समारोह। तो कुछ कंपाइलर्स (जो पहले बाएं तर्क का मूल्यांकन करते हैं) पर कोड 10, 10 और अन्य पर (जो सही तर्क का मूल्यांकन करता है) आउटपुट करेगा, यह 11, 10 आउटपुट करेगा। आम तौर पर आपको कभी भी अपरिभाषित व्यवहार पर भरोसा नहीं करना चाहिए।

यह समझने में आपकी सहायता के लिए, कल्पना करें कि समारोह के पहले प्रत्येक तर्क अभिव्यक्ति का मूल्यांकन किया जाता है (ऐसा नहीं है कि यह वास्तव में वास्तव में कैसे काम करता है, यह सोचने का एक आसान तरीका है जो आपको समझने में मदद करेगा अनुक्रमण):

int arg1 = x;  // This line 
int arg2 = x++;  // And this line can be swapped. 
print(arg1, arg2); 

सी ++ मानक कहता है कि दो तर्क अभिव्यक्ति का परिणाम नहीं है। इसलिए, यदि हम इस तरह की अलग-अलग पंक्तियों पर तर्क अभिव्यक्ति लिखते हैं, तो उनका आदेश महत्वपूर्ण नहीं होना चाहिए, क्योंकि मानक कहता है कि उनका मूल्यांकन किसी भी क्रम में किया जा सकता है। ,

int arg2 = x++;  // And this line can be swapped. 
int arg1 = x;  // This line 
print(arg1, arg2); 

कि यह बहुत स्पष्ट है कि कैसे arg2 मूल्य 10 पकड़ सकता है, जबकि arg1 मूल्य 11 रखती है: कुछ compilers ऊपर क्रम में इनका मूल्यांकन हो सकता है, दूसरों को उन्हें स्वैप कर सकते हैं।

आपको हमेशा अपने कोड में इस अनिर्धारित व्यवहार से बचना चाहिए।

+0

पहली बार मैंने किसी को वास्तव में अपने जवाब में मानक से लिंक किया है, सवाल पूछने के अलावा कि इसे कहां प्राप्त किया जाए। – chris

+0

धन्यवाद, मैं इसे पूरी तरह से प्राप्त करता हूं! अपवित्र होगा लेकिन मेरे पास पर्याप्त कर्म अंक या जो कुछ भी नहीं है। – ordinary

+1

यह स्पष्ट करने के लिए कि यह अनिर्धारित व्यवहार नहीं है बल्कि केवल निर्दिष्ट व्यवहार है। दोनों अलग-अलग हैं। –

4

x ++ एक समारोह पैरामीटर है और वे एक अनिर्दिष्ट आदेश जिसका अर्थ व्यवहार अपरिभाषित और पोर्टेबल नहीं (या कानूनी) है में मूल्यांकन किया जा सकता है।

+0

असल में, यह केवल निर्दिष्ट व्यवहार नहीं है बल्कि अधिक महत्वपूर्ण बात यह है कि यह अनिर्धारित व्यवहार है। मेरा जवाब जांचें। –

0

मेरा मानना ​​है कि इसे फ़ंक्शन कॉल स्टैक के साथ करना है जहां अंतिम तर्क पहले होता है। तो एक्स ++ आपका वाई और एक्स प्रिंट में स्थानीय एक्स है()। एक अपरिभाषित व्यवहार में

print(x, x++); 

परिणाम:

6
बयान

एक कुल मिलाकर। एक बार एक प्रोग्राम में एक अनिर्धारित व्यवहार होता है, यह एक वैध सी ++ कार्यक्रम बन जाता है और सचमुच कोई व्यवहार संभव है। इसलिए इस तरह के कार्यक्रम के लिए तर्क ढूंढना व्यर्थ है।


Why is this Undefined Behavior?

बात करने के लिए कदम से कदम कार्यक्रम का मूल्यांकन करते हैं, जहां किसी भी संदेह से परे साबित कर सकते हैं कि यह अपरिभाषित व्यवहार का कारण बनता है की सुविधा देता है।

एक समारोह के लिए तर्क के मूल्यांकन का क्रम है अनिर्दिष्ट[रेफरी 1]

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

अपने समारोह कॉल करने के लिए उपर्युक्त नियम को लागू करने:

print(x, x++); 

एक कार्यान्वयन के मूल्यांकन हो सकता है इस के रूप में:

  • बाएं से दाएं या
  • वाम का अधिकार
  • या
  • कोई जादुई आदेश (दो से अधिक फ़ंक्शन तर्कों के मामले में)

संक्षेप में आप किसी भी विशिष्ट आदेश का पालन करने के लिए कार्यान्वयन पर भरोसा नहीं कर सकते क्योंकि इसे सी ++ मानक के अनुसार आवश्यक नहीं है।

सी/C++ में आप पढ़ सकते हैं या एक हस्तक्षेप sequence pointबिना एक चर एक बार से अधिक पर लिख नहीं सकता [रेफरी 2] तो यह या तो की है कि क्या का एक अपरिभाषित Behavior.Irrespective में जो परिणाम हैं.यदि आप कर तर्कों को पहले कहा गया कार्य में मूल्यांकन किया जाता है, उनके बीच कोई अनुक्रम बिंदु नहीं है, अनुक्रम बिंदु केवल सभी फ़ंक्शन तर्कों के मूल्यांकन के बाद मौजूद है [रेफरी 3]

इस मामले में x को किसी भी मध्यवर्ती अनुक्रम बिंदु के बिना एक्सेस किया जा रहा है और इसलिए इसका परिणाम एक अनिर्धारित व्यवहार में होता है।

सीधे शब्दों में कहें यह सबसे अच्छा है किसी भी कोड है जो इस तरह अपरिभाषित व्यवहार आह्वान नहीं करता है क्योंकि एक बार आप ऐसा करेंगे तो आप इस तरह के कार्यक्रम से किसी भी विशिष्ट व्यवहार उम्मीद नहीं कर सकते लिखने के लिए।


[रेफरी 1]सी ++ 03 स्टैंडर्ड §5.2.2.8
पैरा 8:

[...] The order of evaluation of function arguments is unspecified. [...]


[रेफरी 2]सी + +03 5 अभिव्यक्तियां [expr]:
पैरा 4:

....
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.


[रेफरी 3]सी ++ 03 1.9 कार्यक्रम निष्पादन [परिचय।निष्पादन]:
पैरा 17: `त्रुटि:

When calling a function (whether or not the function is inline), there is a sequence point after the evaluation of all function arguments (if any) which takes place before execution of any expressions or statements in the function body.

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