C ++ में शिफ्ट ऑपरेशन के बाद बिट-फ़ील्ड का एक अहस्ताक्षरित int एक हस्ताक्षरित int क्यों बन जाता है? [डुप्लिकेट]
परीक्षण कोड:
struct A
{
uint32_t lo : 16;
uint32_t hi : 16;
};
int main()
{
A a{};
a.lo = 0xFFFF;
auto b = a.lo << 16;
cout << b << endl;
return 0;
}
आउटपुट है: -65536
और का प्रकार है b
, int
लेकिन नहीं uint32_t
।
मैंने पाया है कि, uint16_t
और uint8_t
शिफ्ट ऑपरेटर के बाद भी इंट्री हो जाएगी, और इसी तरह का एक प्रश्न था C#
, जो इस निष्कर्ष पर पहुंचा कि जब ऑपरेंड <32 बिट्स हो तो परिणाम पर हस्ताक्षर किए जाएंगे। शिफ्ट ऑपरेशन हमेशा एक हस्ताक्षरित परिणाम में क्यों होते हैं जब ऑपरेंड <32 बिट्स होता है
लेकिन इसका प्रकार a.lo
स्पष्ट रूप से है uint32_t
, जिसे सत्यापित किया जा सकता है decltype(a.lo)
, इसलिए इसे कैसे समझाया जा सकता है?
जवाब
यह मानक अभिन्न संवर्धन का हिस्सा है।
[expr.shift]
1 शिफ्ट ऑपरेटर
<<
और>>
समूह बाएं से दाएंऑपरेंड अभिन्न या अनकैप्ड एन्यूमरेशन प्रकार के होंगे और इंटीग्रल प्रमोशन किए जाते हैं। परिणाम का प्रकार पदोन्नत बाएं ऑपरेंड है।
[conv.prom]
5 एक अभिन्न बिट क्षेत्र ([class.bit]) के लिए एक prvalue प्रकार का एक prvalue में बदला जा सकता
int
है, तोint
थोड़ा-क्षेत्र के सभी मूल्यों का प्रतिनिधित्व कर सकते हैं; अन्यथा, यह करने के लिए परिवर्तित किया जा सकताunsigned int
है, तोunsigned int
थोड़ा-क्षेत्र के सभी मूल्यों का प्रतिनिधित्व कर सकते हैं। यदि बिट-फ़ील्ड अभी तक बड़ा है, तो कोई भी अभिन्न पदोन्नति इस पर लागू नहीं होती है। यदि बिट-फ़ील्ड में एक एन्यूमरेटेड प्रकार है, तो इसे प्रचार उद्देश्यों के लिए उस प्रकार के किसी भी अन्य मान के रूप में माना जाता है।
आपके बाएं ऑपरेंड (बिट-फ़ील्ड) का प्रचार एक उत्पादन करता है int
, और इसलिए यह पूरी पारी की अभिव्यक्ति का प्रकार है। इस प्रकार b
एक है int
प्लेसहोल्डर प्रकार कटौती से भी।