This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Manipulating bit fields is behaving inconsistently


On Fri, Feb 19, 2016 at 12:14 PM, Wink Saville <wink@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.guenther@gmail.com>
> wrote:
>>
>> On Thu, Feb 18, 2016 at 5:31 PM, Wink Saville <wink@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.edlinger@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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]