2016-11-10 7 views
7

उदाहरण अपरिभाषित व्यवहार का एक उदाहरण पूर्णांक अतिप्रवाह पर व्यवहार है। C11dr §3.4.3 3जब अधिकतम मूल्य पर 'int` और पोस्टफिक्स ++ के साथ परीक्षण किया गया है, तो कोड अच्छी तरह परिभाषित है?

int अतिप्रवाह अपरिभाषित व्यवहार है, लेकिन उस जिसके बाद पाश मौजूद है पर लागू होता है, और बाहर के दायरे i अब के पक्ष प्रभाव का उपयोग नहीं करता? विशेष रूप से, क्या यह पोस्टफिक्स वृद्धि spec सहायता करता है?

... परिणाम की मान गणना के साइड इफेक्ट से पहले अनुक्रमित होती है जो ऑपरेंड के संग्रहीत मूल्य को अद्यतन करती है। ... §6.5.2.4 2

साथ बिना चेतावनी के संकलित अच्छी तरह से सक्षम C11

#include <limits.h> 
#include <stdio.h> 

int main(void) { 
    // Specified behavior when `i` has the value `INT_MAX`? 
    for (int i = INT_MAX - 2; i++ < INT_MAX;) { 
    printf("%d\n", i); 
    } 
    puts("Done"); 
    return 0; 
} 

नमूना उत्पादन

2147483646 
2147483647 
Done 

बेशक कोड इस उलझन से बचने के लिए फिर से लिखा जा सकता है नीचे के साथ। फिर भी, उपरोक्त से संबंधित पुष्टि की तलाश में। (मुझे लगता है कि यह यूबी है।) एक समान समस्या INT_MIN और i-- के साथ मौजूद है।

for (int i = INT_MAX - 2; i < INT_MAX;) { 
    i++; 
    printf("%d\n", i); 
    } 

GNU C11 (GCC) version 5.3.0 (i686-pc-cygwin) 
    compiled by GNU C version 5.3.0, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3 
'-std=c11' '-O0' '-g3' '-Wpedantic' '-Wall' '-Wextra' '-Wconversion' '-c' '-fmessage-length=0' '-v' '-MMD' '-MP' '-MF' xx.o' '-o' 'xx.o' '-mtune=generic' '-march=i686' 
/usr/lib/gcc/i686-pc-cygwin/5.3.0/cc1.exe -quiet -v -MMD xx.d -MF xx.d -MP -MT xx.o -dD -Dunix -idirafter ... xx.c 
+1

मुझे भ्रमित किया जा सकता है, लेकिन मुझे नहीं लगता कि मैं वास्तव में किसी भी मामले में ओवरफ्लो करता हूं, यह तब नहीं रुकता है जब यह INT_MAX – Vality

+0

@ वैलिटी हां के बराबर होता है, जैसा कि दिखाया गया है कि 'i ++ 'लौटाए गए INT_MAX' में निष्पादित किया गया था नमूना उत्पादन। सवाल यह है कि अगर यह अच्छी तरह से परिभाषित व्यवहार है। – chux

उत्तर

4

गुंजाइश i के बावजूद, कार्यक्रम i++ की evaluaton में व्यवहार अपरिभाषित है जब i 2147483647 (अपने सिस्टम पर INT_MAX = 2147483647 कल्पना करते हुए) है।

आपका उदाहरण के रूप में फिर से लिखा जा सकता है:

include <limits.h> 

int main(void) { 
    // Specified behavior when `i` has the value `INT_MAX`? 
    { 
     int i = INT_MAX; 
     i++; 
    } 
    puts("Done"); 
    return 0; 
} 

की i++ परिणाम पूर्णांक अतिप्रवाह में मूल्य गणना परिकलित मान प्रयोग किया जाता है या यदि वह वस्तु संघर्ष अगले अनुक्रम बिंदु के बाद सही अस्तित्व के लिए चाहे ; ऑब्जेक्ट का अनुक्रम बिंदु या संग्रहण अवधि अप्रासंगिक है कि यहां एक अपरिभाषित व्यवहार है या नहीं।

+0

अच्छा बिंदु। एक करीबी कोड 'जबकि (1) {int i = INT_MAX हो सकता है; अगर (i ++ == INT_MAX) तोड़ें; } 'जैसा कि मैं समझने की कोशिश कर रहा हूं कि, यदि संभव हो, तो' i ++ 'विभाजित है। परिणाम प्रति spec वृद्धि से पहले अनुक्रमित है। मुझे लगता है कि सवाल यह हो सकता है कि यदि 'if (_test_the return_value_)' लंबित '++' यूबी से बच निकला है - स्पष्ट रूप से नहीं। – chux

4

कोड व्यवहार अपरिभाषित है। अभिव्यक्ति i++i+1 का मूल्यांकन और i के परिणाम का असाइनमेंट का कारण बनती है, और i+1 के मूल्यांकन में अपरिभाषित व्यवहार है। इससे कोई फर्क नहीं पड़ता कि आप i+1 या i के नए संग्रहीत मूल्य के परिणाम का उपयोग नहीं करते हैं। यूबी परिणाम का उपयोग करने की बात नहीं है। इसी तरह, 0*(INT_MAX+1) में यूबी है।

+0

'0 * (INT_MAX + 1)' के बारे में सहमत है यूबी - लेकिन उस उदाहरण में कोई अनुक्रम/स्कोप समस्या नहीं है। यहां 'i ++' का _side-effect_ है और परिणाम के बाद अनुक्रमित है। यह वह विशेषता है जिसे मैं सोच रहा हूं। – chux

+0

मुझे नहीं लगता कि आप कैसे सोचते हैं कि यूबी का अनुक्रमण यूबी है या नहीं। अनुक्रमण के बारे में उद्धृत पाठ उन मामलों में प्रासंगिक है जहां परिणाम परिभाषित किया गया है; इसका उन मामलों में कोई अर्थ नहीं है जहां कार्यक्रम ने व्यवहार को अपरिभाषित किया है। –

+0

'i chux

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