2012-01-26 18 views
20

मैं बस सोच रहा था कि कैसे विनाशकारी पूर्णांक अतिप्रवाह वास्तव में है। 32 बिट प्लेटफार्मों परसी ++ में पूर्णांक कितना विनाशकारी है?

#include <iostream> 

int main() 
{ 
    int a = 46341; 
    int b = a * a; 
    std::cout << "hello world\n"; 
} 

a * a के बाद से अतिप्रवाह, और पूर्णांक अतिप्रवाह अपरिभाषित व्यवहार से चलाता है, मैं सभी कि hello world वास्तव में मेरे स्क्रीन पर दिखाई देगा पर किसी भी गारंटी देता है की क्या ज़रूरत है: निम्न उदाहरण कार्यक्रम ले लो?


मैं अपने सवाल से "पर हस्ताक्षर किए" भाग निम्न मानक उद्धरण के आधार पर निकाल:

(§5/5 सी ++ 03, §5/4 सी ++ 11) हैं अभिव्यक्ति के मूल्यांकन के दौरान, परिणाम गणितीय रूप से परिभाषित नहीं है या इसके प्रकार के लिए प्रतिनिधित्व योग्य मूल्यों की सीमा में नहीं है, व्यवहार अपरिभाषित है।

(§3.9.1/4) unsigned घोषित बिना हस्ताक्षर किए गए पूर्णांक, अंकगणित मॉड्यूलो 2^एन के नियमों का पालन करेंगे जहां एन पूर्णांक के उस विशेष आकार के मान प्रतिनिधित्व में बिट्स की संख्या है। इसका तात्पर्य है कि हस्ताक्षरित अंकगणित ओवरफ्लो नहीं होता है जिसके परिणामस्वरूप परिणामस्वरूप हस्ताक्षरित पूर्णांक प्रकार द्वारा प्रतिनिधित्व नहीं किया जा सकता है, जो मॉड्यूल को कम करता है जो कि सबसे बड़ा मान से अधिक होता है जिसे परिणामस्वरूप हस्ताक्षरित पूर्णांक प्रकार द्वारा दर्शाया जा सकता है।

+1

मैं कभी नहीं देखा है सी में एक अतिप्रवाह ++ एक मुद्दा होता है। संख्या बस खुशी से लपेट जाएगी और प्रोसेसर पर ओवरफ्लो ध्वज सेट करेगा। – Brain2000

+7

@ ब्रेन 2000 वे ज्यादातर अनुकूलन के मुद्दों का कारण बनते हैं। जैसे कि '(ए + 1> ए)' ओवरफ्लो के बावजूद हमेशा सत्य होता है। – Pubby

+0

[जीसीसी विफलता का संभावित डुप्लिकेट? या अपरिभाषित व्यवहार?] (Http://stackoverflow.com/questions/7682477/gcc-fail-or-undefined-behavior) – Xeo

उत्तर

19

के रूप में टिप्पणी में @Xeo द्वारा बताया (मैं वास्तव में इसे C++ chat पहले में लाया):
अपरिभाषित व्यवहार वास्तव में इसका मतलब है और यह आप हिट जब आप कम से कम यह उम्मीद कर सकते हैं।

इस का सबसे अच्छा उदाहरण यहाँ है: Why does integer overflow on x86 with GCC cause an infinite loop?

86 पर, पर हस्ताक्षर किए पूर्णांक अतिप्रवाह सिर्फ एक सरल चादर के आसपास है। तो सामान्यतः, आप सी या सी ++ में एक ही चीज़ होने की उम्मीद करेंगे। हालांकि, कंपाइलर हस्तक्षेप कर सकता है - और अपरिभाषित व्यवहार का उपयोग को अनुकूलित करने का अवसर के रूप में करें।

उदाहरण उस सवाल से लिया में:

#include <iostream> 
using namespace std; 

int main(){ 
    int i = 0x10000000; 

    int c = 0; 
    do{ 
     c++; 
     i += i; 
     cout << i << endl; 
    }while (i > 0); 

    cout << c << endl; 
    return 0; 
} 

जब जीसीसी के साथ संकलित, जीसीसी पाश परीक्षण बाहर का अनुकूलन और इस अनंत लूप बना देता है।

+2

इस घटना का एक और उदाहरण यहां है -> http://stackoverflow.com/questions/7124058/compiler-optimization-causing-program-to-run-slower – Joe

8

आप कुछ हार्डवेयर सुरक्षा सुविधा को ट्रिगर कर सकते हैं। तो नहीं, आपके पास कोई गारंटी नहीं है।

संपादित करें: ध्यान दें कि gcc में -ftrapv विकल्प है (लेकिन यह मेरे लिए काम नहीं करता है)।

+4

'-ftrapv' सिग्नल के लिए हैंडलर पंजीकृत करते समय केवल कुछ भी करता है। यह किसी भी दुर्घटना या किसी अन्य अवलोकन योग्य व्यवहार का कारण नहीं बनता है। – sepp2k

+0

'-ftrapv' के बजाय क्या आप हस्ताक्षर किए गए ओवरफ्लो को हस्ताक्षरित ओवरफ्लो को संभालने के लिए '-फ्रप्रव' एक्सटेंशन के बारे में सोच रहे हैं? –

5

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

जबकि ओवरब्लो के बारे में यूबी शायद हार्डवेयर हार्डवेयर को लेने के लिए पेश किया गया है जो ओवरफ्लो पर जाल या संतृप्त होता है और प्रतिनिधित्व के बीच परिणाम का अंतर होता है, और इसलिए इस मामले में पहले दृश्य के लिए बहस कर सकती है, लोग ऑप्टिमाइज़र लिखते हैं काफी हद तक यह देखते हैं कि यदि मानक कुछ गारंटी नहीं देता है, तो वास्तव में कुछ भी हो सकता है और वे मशीन कोड उत्पन्न करने के लिए स्वतंत्रता के प्रत्येक टुकड़े का उपयोग करने का प्रयास करते हैं जो अधिक तेज़ी से चलता है, भले ही नतीजा अब और समझ में न आए।

तो जब आप एक अपरिभाषित व्यवहार देखते हैं, मान लेते हैं कि कुछ भी हो सकता है, तथापि उचित किसी दिए गए व्यवहार लग सकता है।

+2

पूर्णांक ओवरफ़्लो के बारे में अपरिभाषित व्यवहार कई प्लेटफार्मों को पर्याप्त अनुकूलन करने की अनुमति देता है अन्यथा संभव नहीं होगा। उदाहरण के लिए, अगर एक ही रास्ता पूर्णांकों x और y नकारात्मक हो सकता है अतिप्रवाह के माध्यम से हो सकता है, एक संकलक 'अहस्ताक्षरित अंकगणित (जो एक निर्देश और एक समारोह कॉल के बीच का अंतर हो सकता है) का उपयोग कर की गणना कर सकते हैं एक्स/y'। यह बहुत बुरा है कि कोई हस्ताक्षरित प्रकार नहीं है जहां अतिप्रवाह यूबी होगा, क्योंकि वहां कुछ अनुकूलन भी संभव हो जाएंगे। – supercat

+0

हालांकि, मुझे यह उल्लेख करना चाहिए कि, हालांकि, सबसे उपयोगी अनुकूलन के लिए पूर्णांक अनुकूलन की आवश्यकता नहीं होती है, जो कभी भी एक बकवास मूल्य उत्पन्न करने से परे कोई परिणाम नहीं होता है जो कि अजीब तरीके से व्यवहार कर सकता है (उदाहरण के लिए शून्य से कम और कम से कम होना प्रतीत होता है शून्य)। सी मानक के पास यूबी के अलावा अन्य चीजों का वर्णन करने का कोई तरीका नहीं है, लेकिन गारंटी है कि गणनाओं का कोई दुष्प्रभाव नहीं होगा, जो आमतौर पर प्रदान करने के लिए बहुत सस्ता है और बेहद मूल्यवान है। यह बहुत खराब कंपाइलर अब लगातार प्रदान नहीं करते हैं। – supercat

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

  • कोई संबंधित समस्या नहीं^_^