This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Manipulating bit fields is behaving inconsistently
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Wink Saville <wink at saville dot com>
- Cc: Bernd Edlinger <bernd dot edlinger at hotmail dot de>, "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Fri, 19 Feb 2016 12:31:37 +0100
- Subject: Re: Manipulating bit fields is behaving inconsistently
- Authentication-results: sourceware.org; auth=none
- References: <HE1PR07MB090588653DC1A71961F97195E4AF0 at HE1PR07MB0905 dot eurprd07 dot prod dot outlook dot com> <CAKk8isp3AuFJ=_daThz-WF2VZp2vzQSsTrC0-XGLi53u9SP5Og at mail dot gmail dot com> <CAFiYyc340VY3qQpbG7=tJxCBRmooMdUA-wFvxChfGNvkC9FN9Q at mail dot gmail dot com> <CAKk8isrQFetoAhpNHVHmBY5zY9uANAnuoHTvEig69mDVwFd0Xg at mail dot gmail dot com>
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.