On Fri, Feb 19, 2016 at 12:14 PM, Wink Saville <w...@saville.com> wrote: > Can you point me to previous discussions, or maybe some search terms? I'm > curious about the rationale for the odd behavior.
I don't remember discussions about a specific decision how to implement the GCC extension but I remember when fixing bugs that it was pointed out how the standard does not say those types promote. Of course those types don't exist in the standard. Richard. > > On Fri, Feb 19, 2016, 12:37 AM Richard Biener <richard.guent...@gmail.com> > wrote: >> >> 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.