2011-02-05 9 views
13

क्या मुझे भरोसा है कि सी संकलक प्रत्येक बार थोड़ा सा फ़ील्ड एक्सेस करते समय मॉड्यूल 2^एन करता है? या क्या कोई संकलक/अनुकूलन है जहां नीचे दिए गए कोड जैसे कोड ओवरफ़्लो प्रिंट नहीं करेंगे?बिट फ़ील्ड में ओवरफ़्लो

struct { 
    uint8_t foo:2; 
} G; 

G.foo = 3; 
G.foo++; 

if(G.foo == 0) { 
    printf("Overflow\n"); 
} 

अग्रिम धन्यवाद, फ्लोरियन

+0

आपका क्या मतलब है? आपने स्पष्ट रूप से इसे दो बिट्स में डेटा स्टोर करने के लिए कहा है। इसके अलावा, 3 + 1 == 0 मॉड 4 –

+0

यदि आप उस संरचना में अन्य बिटकफील्ड घोषित कर चुके हैं तो मैं उस बिट के साथ क्या होता हूं इसके बारे में अधिक चिंतित होगा। जैसे uint8_t बार: 2; uint8_t foo: 2; uint8_t पू: 2; क्या यह बार या पू को प्रभावित करेगा? – Dave

+0

foo क्या करता है: 2 मतलब है? – CharlesB

उत्तर

11

हां, आप सी कंपाइलर पर सही काम करने के लिए भरोसा कर सकते हैं, जब तक कि बिट फ़ील्ड को एक हस्ताक्षरित प्रकार के साथ घोषित किया गया हो, जिसमें आपके पास uint8_t है। सी 99 मानक §6.2.6.1/3:

हस्ताक्षरित बिट-फ़ील्ड में संग्रहीत मान और बिना हस्ताक्षरित चार प्रकार की वस्तुओं को शुद्ध बाइनरी नोटेशन का उपयोग करके दर्शाया जाएगा। 40)

§6.7.2.1/9 से:

थोड़ा-क्षेत्र एक हस्ताक्षरित या अहस्ताक्षरित पूर्णांक बिट्स की निर्धारित संख्या से मिलकर प्रकार के रूप में व्याख्या की है। 104) यदि मान 0 या 1 को _Bool प्रकार के गैर-शून्य-चौड़ाई बिट-फ़ील्ड में संग्रहीत किया गया है, तो बिट-फ़ील्ड का मान संग्रहीत मूल्य के बराबर की तुलना करेगा।

और §6.2.5/9 (जोर मेरा) से:

एक हस्ताक्षरित पूर्णांक प्रकार के गैर नकारात्मक मानों की श्रेणी इसी अहस्ताक्षरित पूर्णांक प्रकार का एक subrange है, और के प्रतिनिधित्व प्रत्येक प्रकार में एक ही मूल्य समान है। 31)हस्ताक्षर किए गए ऑपरेटरों को शामिल करने वाली गणना कभी भी बहती नहीं जा सकती है, जिसके परिणामस्वरूप परिणामस्वरूप हस्ताक्षरित पूर्णांक प्रकार द्वारा प्रतिनिधित्व नहीं किया जा सकता है, यह परिणाम मॉड्यूलो को कम करता है जो कि सबसे बड़ा मान से अधिक होता है जिसे परिणामी प्रकार से दर्शाया जा सकता है।

तो हाँ, आप यह सुनिश्चित करें कि किसी भी मानक-अनुरूप संकलक किसी भी अन्य अवांछित दुष्प्रभावों के बिना 0 करने के लिए G.foo अतिप्रवाह होगा हो सकता है।

+0

जैसा कि आर द्वारा मुझे बताया गया है .. नीचे एक टिप्पणी में, गणना वास्तव में एक हस्ताक्षरित गणना है। यह यहां जवाब नहीं बदलता है, लेकिन यह कहता है कि एक आर्किटेक्चर पर 31-बिट हस्ताक्षरित बिटफील्ड के साथ, जहां इन्ट्स 32-बिट (जहां एक अपरिभाषित हस्ताक्षर ओवरफ्लो हो सकता है)। –

3

सं संकलक क्षेत्र के लिए 2 बिट्स आबंटित करता है, और बढ़ाने 100b, में 3 परिणाम जो जब 0.

0

लघु जवाब में में दो बिट्स परिणाम रखा : हाँ, आप मॉड्यूलो 2^एन होने पर भरोसा कर सकते हैं।

आपके प्रोग्राम में, G.foo++; वास्तव में G.foo = (unsigned int)G.foo + 1 के बराबर है।

बिना हस्ताक्षर किए गए int अंकगणित हमेशा 2^(बिट्स में हस्ताक्षरित int का आकार) परिणाम उत्पन्न करता है। कम से कम वजन के दो बिट्स को G.foo में संग्रहीत किया जाता है, जो शून्य उत्पादन करते हैं।

+0

आपका समतुल्य गलत है। 'uint8_t' को 'int' पर प्रचारित किया जाएगा, न कि 'हस्ताक्षरित int'। 'जी.फू ++;' जी.फू = ((int) जी के बराबर है।foo + 1)% 4; '। –

+0

@ आर .. आप सही हैं (मुझे हमेशा इन प्रचारों को गलत लगता है), लेकिन फिर ऊपर दिए गए एडम के उत्तर से कुछ गायब है, यह है कि +1 वास्तव में हस्ताक्षरित इंक के बीच हो रहा है। –

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