C और C++ 2014 तक पूर्व के सभी संस्करणों में, लेखन1 << 31 क्यों कार्यान्वित किया गया-सी ++ 14 में परिभाषित किया गया?
1 << (CHAR_BIT * sizeof(int) - 1)
वजह से अपरिभाषित व्यवहार है, क्योंकि बाएं स्थानांतरण 2
द्वारा लगातार गुणा के बराबर होने के रूप में परिभाषित किया गया है, और इस बदलाव का कारण बनता है पर हस्ताक्षर किए पूर्णांक अतिप्रवाह:
सी ++ 14 में
E1 << E2
का परिणामE1
E2
बिट स्थिति स्थानांतरित हो गया है; खाली बिट्स शून्य से भरे हुए हैं। [...] यदिE1
पर एक हस्ताक्षरित प्रकार और nonnegative मान है, औरE1
× 2 ई 2 परिणाम प्रकार में प्रतिनिधित्व योग्य है, तो यह परिणामस्वरूप मान है; अन्यथा, व्यवहार अपरिभाषित है।
हालांकि पाठ <<
के लिए बदल गया है लेकिन गुणन के लिए नहीं:
E1 << E2
का मूल्यE1
बाएं स्थानांतरित कर दियाE2
बिट पदों है; खाली बिट्स शून्य से भरे हुए हैं। [...] अन्यथा, यदिE1
एक हस्ताक्षरित प्रकार और गैर-नकारात्मक मान, औरE1
× 2 E2 है प्रदर्शनीय में परिणाम प्रकार की अहस्ताक्षरित प्रकार, तो उस मूल्य इसी है, परिणाम प्रकार के लिए परिवर्तित, परिणामी मूल्य है; अन्यथा, व्यवहार अपरिभाषित है।
व्यवहार अब हस्ताक्षर किए प्रकार के बाहर के रेंज काम के लिए के रूप में ही, यानी के रूप में द्वारा [conv.integral]/3 कवर किया गया है:
तो गंतव्य प्रकार हस्ताक्षरित किया गया है, मान अपरिवर्तित है यदि इसे गंतव्य प्रकार (और बिट-फील्ड चौड़ाई) में प्रदर्शित किया जा सकता है; अन्यथा, मान कार्यान्वयन-परिभाषित है।
इसका मतलब है कि यह अभी भी 1 << 31
(32-बिट int के साथ सिस्टम पर) लिखने के लिए गैर पोर्टेबल है। तो सी ++ 14 में यह परिवर्तन क्यों किया गया था?
+1 हॉवर्ड हिन्नेंट [इस विषय पर टिप्पणियां] (http://stackoverflow.com/questions/19593938/is-left-shifting-a-negative-integer-undefined-behavior-in-c11#comment29091986_19593938), मुझे याद रखने का एकमात्र कारण यह है कि टिप्पणी इस [प्रश्न] (http://stackoverflow.com/q/21319413/1708801) के लिए मेरी प्रेरणा का हिस्सा थी। –
कल्पना कीजिए कि अगर उन्होंने इसके बजाय कुछ ऐसा कहा था: "बाधाएं: प्रचार के बाद, बाएं ऑपरेंड ई 1 एक हस्ताक्षरित पूर्णांक प्रकार होगा"। यह मानव जाति को सूक्ष्म, शिफ्ट से संबंधित बग की खगोलीय मात्रा से बचा लेगा। कि शब्दों की – Lundin