2017-02-03 19 views
21

मुझे पता है कि i=i++; एक अपरिभाषित व्यवहार है, क्योंकि i अनुक्रम बिंदु ; से पहले दो बार बदला जाता है।निम्नलिखित एक अपरिभाषित व्यवहार है? i = func (i)

लेकिन मैं संकलक मामले की गारंटी देता है, तो के रूप में नीचे एक अपरिभाषित व्यवहार नहीं है पता नहीं है:

int func(int &i) 
{ 
    i++; 
    return i; 
} 

int i = 1; 
i = func(i); 
+0

क्या संकलक बताता है इस प्रकार है लग सकता है सुरक्षा को दिखाता है? – tristan

+24

@tristan आम तौर पर, कंपाइलर यूबी के बारे में कुछ भी नहीं बताता है। – user2079303

+0

जीसीसी में 'परिणाम-बिंदु' विकल्प – tristan

उत्तर

44
सबसे पहले

, आधुनिक सी ++ "अनुक्रम अंक" के पुराने (अपर्याप्त) अवधारणा से पर स्विच किया गया है "अनुक्रमण" की नई अवधारणा (यानी "अनुक्रमित", "अनुक्रमित")। जबकि i = i++ अभी भी अपरिभाषित है, i = ++i वास्तव में अब पूरी तरह से परिभाषित किया गया है। कई lvalue-returning ऑपरेटरों में अनुक्रम नियमों का पुनर्वितरण किया गया था।

दूसरा, आपका संस्करण पुराने विनिर्देश के साथ-साथ नए के तहत सुरक्षित है। फ़ंक्शन के अंदर i का संशोधन असाइनमेंट से i पर सुरक्षित रूप से "पृथक" है। शुरुआत में और फ़ंक्शन के अंत में क्लासिक विनिर्देश अनुक्रम बिंदुओं में एक दूसरे से i के संशोधनों (और पढ़ने) को सुरक्षित रूप से अलग कर दिया गया। नए अनुक्रमण नियम भी सुरक्षा के समान स्तर को संरक्षित करते हैं।

एक उदाहरण है कि एक समारोह कॉल द्वारा प्रदान के रूप में

int inc(int &i) { return i++; } 
... 
int i = 1; 

int r1 = i++ * i++ * i++;   
// Undefined behavior because of multiple unsequenced side effects 
// applied to the same variable 

int r2 = inc(i) * inc(i) + inc(i); 
// No UB, but order of evaluation is unspecified. Since the result 
// depends on the order of evaluation, it is unspecified 

int r3 = inc(i) + inc(i) + inc(i); 
// Perfectly defined result. Order of evaluation is still unspecified, 
// but the result does not depend on it 
+0

"फ़ंक्शन के अंदर मैं संशोधन को सुरक्षित रूप से" अलगाव "से बाहर कर रहा हूं।" क्या होगा यदि संकलक फ़ंक्शन को रेखांकित करता है? या यूबी के लिए संभावित मतलब है कि संकलक इस विशिष्ट मामले को रेखांकित नहीं करेगा? – JAB

+4

@ जेएबी: इनलाइनिंग फ़ंक्शन कॉल के अनुक्रमिक अर्थशास्त्र (या किसी भी अन्य अर्थशास्त्र) को किसी भी तरह से परिवर्तित नहीं करती है। कंपाइलर किसी भी समय चाहे जो चाहें इनलाइन करने के लिए स्वतंत्र है, लेकिन परिणामी कोड को मूल सार अर्थशास्त्र को पूरी तरह से संरक्षित करना चाहिए। अर्थात। इनलाइन कॉल का व्यवहार गैर-रेखांकित कॉल के व्यवहार के समान होना चाहिए। कंपाइलर को इनलाइनिंग से रोकने के लिए इस मामले में कुछ भी नहीं है। लेकिन संकलक को याद रखना चाहिए कि इनलाइन संस्करण पूरी तरह से गैर-रेखांकित व्यक्ति के व्यवहार को सुरक्षित रखेगा। – AnT

+0

वैसे यह अच्छा है, क्योंकि मैंने अतीत में इस तरह के व्यवहार का लाभ उठाया है। – JAB

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