Oggi ho scoperto un comportamento allarmante durante la sperimentazione con campi di bit. Per motivi di discussione e di semplicità, ecco un esempio di programma:GCC, -O2 e bitfield: si tratta di un bug o di una funzionalità?
#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);
}
Il programma è volutamente la causa del campo di bit 3 bit per traboccare. Ecco il (corretto) uscita quando elaborato applicando "g ++ -O0":
campo Cast 3 bit a int: 7
campo Cast 3 bit a int: 0
Ecco l'uscita quando compilato utilizzando "g ++ -O2" (e -O3):
campo Cast 3 bit a int: 7
Cast campo 3-bit int: 8
Controllo del montaggio di quest'ultimo esempio, ho trovato questo:
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
Le ottimizzazioni hanno appena inserito "8", assumendo 7 + 1 = 8 mentre in realtà il numero trabocca ed è zero.
Fortunatamente il codice che mi interessa non esagera per quanto ne so, ma questa situazione mi spaventa: si tratta di un bug noto, di una funzionalità o di un comportamento previsto? Quando posso aspettarmi che gcc abbia ragione su questo?
Edit (Re: firmato/unsigned):
E 'trattato come senza segno, perché è dichiarato come non firmato. Dichiarandolo come int si ottiene l'uscita (con O0):
campo getto 3-bit INT: -1
campo getto 3-bit INT: 0
An anche cosa divertente accade con -O2 in questo caso:
campo Cast 3 bit a int: 7
campo Cast 3 bit a int: 8
Ammetto che l'attributo è una cosa di pesce da usare; in questo caso è una differenza nelle impostazioni di ottimizzazione di cui sono preoccupato.
chedcked gcc 4.4.1 - l'output è 7/0 con/senza ottimizzazione – dimba
Ammetto che sto usando 4.1.2 - grazie per l'heads up. – Rooke
Cosa succede se metti '__attribute __ ((__ imballato __))' dopo l'intera struttura? –