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


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?

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]