On Thu, Feb 18, 2016 at 5:31 PM, Wink Saville <w...@saville.com> wrote: > You've convinced me that this isn't a bug, but I assume you'd agree > its weird at best. I tested it with clang and it works as I'd expect: > > $ make > clang -x c -m64 -O3 -Wall -o test.o -c test.c > objdump -d test.o > test.txt > clang -m64 -O3 -Wall test.o -o test > wink@wink-desktop:~/prgs/large_fields_are_odd > $ ./test > x.f0=0xfff > g0=0x1ffe expect 0x1ffe > x.f1=0xfffffffffffff > g1=0x1ffffffffffffe expect 0x1ffffffffffffe > > Here is the make file: > > CC = clang > CFLAGS = -m64 -O3 -Wall > > all: test > > test.o: test.c > $(CC) -x c $(CFLAGS) -o test.o -c test.c > objdump -d test.o > test.txt > > test: test.o > $(CC) $(CFLAGS) test.o -o test > > clean: > rm -f test test.o test.txt > > > Do you think gcc should change?
No, clang should. GCC behaved this way since forever. > On Thu, Feb 18, 2016 at 2:52 AM, Bernd Edlinger > <bernd.edlin...@hotmail.de> wrote: >> Hi, >> >>> struct fields { >>> long long unsigned f0:12; >>> long long unsigned f1:52; >>> } __attribute__((__packed__)); >> >> the C99 standard ISO/IEC 9899 forbids this type: >> >> 6.7.2.1 Structure and union specifiers >> >> 4 A bit-field shall have a type that is a qualified or unqualified version >> of _Bool, signed int, >> unsigned int, or some other implementation-defined type. >> >> The C standard simply does not promote the bit-field value to any type >> larger than int or >> unsigned int. >> >> GCC chooses to do the larger than int computations in an artificial 52-bit >> type, but it is a >> non-standard extension. >> >> And if you compile your example with -Wall you'll see the problem: >> >> gcc -m32 -O3 -Wall test.c >> test.c: In function 'main': >> test.c:17:21: warning: format '%llx' expects argument of type 'long long >> unsigned int', but argument 2 has type 'int' [-Wformat=] >> printf("x.f0=0x%llx\n", x.f0); >> ^ >> test.c:19:21: warning: format '%llx' expects argument of type 'long long >> unsigned int', but argument 2 has type 'long long unsigned int:52' >> [-Wformat=] >> printf("x.f1=0x%llx\n", x.f1); >> ^ >> >> so especially the first warning is no joke: >> >> ./a.out >> x.f0=0x80497b400000fff >> g0=0x1ffe expect 0x1ffe >> x.f1=0xfffffffffffff >> g1=0xffffffffffffe expect 0x1ffffffffffffe >> >> >> OTOH that is perfectly OK for C++: >> >> gcc -x c++ -m32 -O3 -Wall test.c >> >> ./a.out >> x.f0=0xfff >> g0=0x1ffe expect 0x1ffe >> x.f1=0xfffffffffffff >> g1=0x1ffffffffffffe expect 0x1ffffffffffffe >> >> >> Regards >> Bernd.