आज मैंने थोड़ा फ़ील्ड के साथ प्रयोग करते समय खतरनाक व्यवहार की खोज की।जीसीसी, -ओ 2, और बिटफील्ड - क्या यह एक बग या सुविधा है?
#include <stdio.h>
struct Node
{
int a:16 __attribute__ ((packed));
int b:16 __attribute__ ((packed));
unsigned int c:27 __attribute__ ((packed));
unsigned int d:3 __attribute__ ((packed));
unsigned int e:2 __attribute__ ((packed));
};
int main (int argc, char *argv[])
{
Node n;
n.a = 12345;
n.b = -23456;
n.c = 0x7ffffff;
n.d = 0x7;
n.e = 0x3;
printf("3-bit field cast to int: %d\n",(int)n.d);
n.d++;
printf("3-bit field cast to int: %d\n",(int)n.d);
}
कार्यक्रम जानबूझकर 3-बिट बिट मैदान ऊपर जाने का कारण है: चर्चा और सादगी के लिए, यहाँ एक उदाहरण कार्यक्रम है। यहाँ (सही) उत्पादन का उपयोग करते समय "जी ++ -O0" संकलित है:
3-सा क्षेत्र डाली int करने के लिए: 7
3-सा क्षेत्र डाली int करने के लिए: 0
यहाँ उत्पादन (और -O3) का उपयोग कर "जी ++ -O2" संकलित:
3-सा क्षेत्र डाली int करने के लिए: 7
3-सा क्षेत्र डाली int करने के लिए: 8
बाद उदाहरण के विधानसभा जाँच हो रही है, मैंने पाया इस:
movl $7, %esi
movl $.LC1, %edi
xorl %eax, %eax
call printf
movl $8, %esi
movl $.LC1, %edi
xorl %eax, %eax
call printf
xorl %eax, %eax
addq $8, %rsp
अनुकूलन बस डाला है "8", 7 + 1 = 8 संभालने जब वास्तव में संख्या overflows और शून्य है।
सौभाग्य से जिस कोड की मुझे परवाह है, वह मुझे बहती नहीं है, लेकिन यह स्थिति मुझे डराता है - क्या यह एक ज्ञात बग, एक विशेषता है, या यह अपेक्षित व्यवहार है? मैं इस बारे में जीसीसी की सही कब उम्मीद कर सकता हूं?
संपादित करें (पुन: पर हस्ताक्षर किए/अहस्ताक्षरित):
यह है क्योंकि यह अहस्ताक्षरित के रूप में घोषित किया है अहस्ताक्षरित के रूप में इलाज किया जा रहा है। यह घोषणा के रूप में पूर्णांक आप (O0 के साथ) आउटपुट प्राप्त:
3-सा क्षेत्र डाली int करने के लिए: -1
3-सा क्षेत्र डाली int करने के लिए: 0
एक भी int करने के लिए
3-सा क्षेत्र डाली: मजेदार बात यह है कि इस मामले में -O2 के साथ होता है 7
3-सा क्षेत्र डाली int करने के लिए: 8
मैं मानता हूं कि विशेषता उपयोग करने के लिए एक फिश चीज है; इस मामले में यह ऑप्टिमाइज़ेशन सेटिंग्स में एक अंतर है जिसके बारे में मुझे चिंतित है।
शेडकेड जीसीसी 4.4.1 - आउटपुट 7/0 के साथ/अनुकूलन के बिना – dimba
मैं मानता हूं कि मैं 4.1.2 का उपयोग कर रहा हूं - सिर के लिए धन्यवाद। – Rooke
यदि आप पूरी संरचना के बाद '__attribute __ ((__ पैक __)) डालते हैं तो क्या होता है? –