Heute entdeckte ich ein alarmierendes Verhalten beim Experimentieren mit Bitfeldern. Aus Gründen der Diskussion und Einfachheit, hier ist ein Beispielprogramm:GCC, -O2 und Bitfelder - ist das ein Fehler oder eine Funktion?
#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);
}
Das Programm absichtlich verursacht das 3-Bit-Bit-Feld überläuft. Hier ist der (richtige) ausgegeben wird, wenn kompiliert "g ++ -O0" verwendet:
3-Bit-Feld cast INT: 7
3-Bit-Feld cast INT: 0
Hier die Ausgabe bei Verwendung von kompilierten "g ++ -O2" (und O3):
3-Bit-Feld cast iNT: 7
3-Bit-Feld Guss int: 8
den Zusammenbau des letzteren Beispiel prüfen, fand ich folgendes:
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
Die Optimierungen "8" gerade eingefügt haben, unter der Annahme, 7 + 1 = 8, wenn in der Tat die Zahl überläuft und ist Null.
Glücklicherweise ist der Code, den ich interessiere, nicht so weit überschwemmt, wie ich weiß, aber diese Situation macht mir Angst - ist das ein bekannter Fehler, ein Feature oder ist dieses erwartete Verhalten? Wann kann ich damit rechnen, dass gcc recht hat?
Edit (re: mit/ohne Vorzeichen):
Es wird als unsigned behandelt, weil sie als unsigned deklariert wird. Deklarieren es als int Sie die Ausgabe (mit O0) erhalten:
3-Bit-Felddarsteller in int: -1
3-Bit-Feld Guss int: 0
Eine noch funnier passiert mit -O2 in diesem Fall:
3-Bit-Felddarsteller in int: 7
3-Bit-Felddarsteller in int: 8
Ich gebe zu, dass Attribut ist eine fischige Sache zu verwenden; In diesem Fall ist es ein Unterschied in den Optimierungseinstellungen, um die ich mich Sorgen mache.
chedcked gcc 4.4.1 - Ausgabe ist 7/0 mit/ohne Optimierung – dimba
Ich gebe zu, ich benutze 4.1.2 - danke für die Köpfe hoch. – Rooke
Was passiert, wenn Sie '__attribute __ ((__ packed __))' hinter die gesamte Struktur stellen? –