EDIT सार्वजनिक स्वास्थ्य चेतावनी - इस प्रश्न में अपरिभाषित व्यवहार के बारे में झूठी धारणा शामिल है। स्वीकृत उत्तर देखें।कोई अपरिभाषित व्यवहार के साथ डबल-चंक जोड़ने के लिए कैसे करें?
recent blog post पढ़ने के बाद, मैं सी और सी ++ कोड में सभी मानकों-अपरिभाषित धारणाओं से बचने की व्यावहारिकता के बारे में बहुत कुछ सोच रहा हूं। यहाँ एक टुकड़ा सी ++ से बाहर काट, एक अहस्ताक्षरित 128 बिट इसके अलावा करने के लिए ...
void c_UInt64_Pair::operator+= (const c_UInt64_Pair &p)
{
m_Low += p.m_Low;
m_High += p.m_High;
if (m_Low < p.m_Low) m_High++;
}
यह स्पष्ट रूप से अतिप्रवाह व्यवहार के बारे में मान्यताओं पर निर्भर करता है। जाहिर है कि ज्यादातर मशीन सही प्रकार के बाइनरी पूर्णांक का समर्थन कर सकती हैं (हालांकि शायद 32-बिट भाग या जो कुछ भी हो), लेकिन स्पष्ट रूप से एक बढ़ता मौका है कि ऑप्टिमाइज़र मानकों को अपरिभाषित व्यवहार कर सकता है। यही कारण है कि m_Low < p.m_Low
स्थिति पास हो सकती है यदि m_Low += p.m_Low
अतिप्रवाह, जो अपरिभाषित व्यवहार है, इसलिए ऑप्टिमाइज़र कानूनी रूप से निर्णय ले सकता है कि हमेशा विफल रहता है। इस मामले में, यह कोड बस टूटा हुआ है।
सवाल है, इसलिए ...
कैसे आप ऊपर के एक यथोचित कुशल संस्करण अपरिभाषित व्यवहार पर निर्भर रहे बिना लिख सकते है?
मान लें कि आपके पास एक उचित 64-बिट बाइनरी मशीन पूर्णांक है, लेकिन आपके पास एक दुर्भावनापूर्ण कंपाइलर है जो हमेशा आपके अपरिभाषित व्यवहार को सबसे खराब (या असंभव) तरीके से समझता है। साथ ही, मान लीजिए कि आप में कुछ विशेष अंतर्निहित, आंतरिक, पुस्तकालय या आपके लिए यह भी करना है।
संपादित नाबालिग स्पष्टीकरण - यह सिर्फ अतिप्रवाह का पता लगाने, लेकिन यह भी सुनिश्चित करना है कि दोनों m_Low और m_High सही सापेक्ष साथ खत्म 2^64 परिणाम है, जो भी मानकों पर अपरिभाषित है के बारे में नहीं है।
1/यह सी नहीं है। आप इस सवाल को "सी" क्यों टैग करते हैं? 2/यदि यह सी थे, और शायद सी ++ में भी, यह अपरिभाषित व्यवहार पर भरोसा नहीं करेगा: हस्ताक्षरित अभिन्न प्रकार ओवरफ़्लो परिभाषित किए गए हैं और मॉड्यूलो व्यवहार है: C99 मानक में 6.2.5.9। –
@ पास्कल: दरअसल, धारा 5 देखें।सबसे हालिया मसौदे में से 4 (मेरे पास सी ++ 03 मानक नहीं है, लेकिन मेरा मानना है कि व्यवहार नहीं बदला है) - "यदि अभिव्यक्ति के मूल्यांकन के दौरान, परिणाम गणितीय रूप से परिभाषित नहीं किया गया है या नहीं इसके प्रकार के लिए प्रतिनिधित्व योग्य मूल्यों की सीमा, व्यवहार अपरिभाषित है। " –
@ पास्कल - (1) प्रश्न सी और सी ++ के समान है। केवल एक में एक उदाहरण प्रदान करना इसका मतलब यह नहीं है कि प्रश्न केवल उस के बारे में है। (2) ऐसा कब हुआ? यदि यह सच है तो यह उत्तर है (सी ++ ने अभी तक प्रासंगिक सी नियम आयात नहीं किया हो सकता है, लेकिन यदि नहीं, तो इसमें कोई संदेह नहीं होगा), इसलिए इसे संदर्भ के साथ उत्तर में रखें और मैं स्वीकार करूंगा। – Steve314