How to use _Generic with bit-fields

Martin Sebor msebor@gmail.com
Fri Feb 19 21:35:00 GMT 2016


On 02/19/2016 11:25 AM, Wink Saville wrote:
> I'm using gcc 5.3.0:
>
> $ gcc --version
> gcc (GCC) 5.3.0
> Copyright (C) 2015 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.  There is NO
> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
>
>
> And I've tried to use _Generic to print the type of a bit field but
> the compiler fails with:
>
> $ make
> gcc -Wall -std=c11 -o test.o -c test.c
> test.c: In function ‘main’:
> test.c:8:35: error: ‘_Generic’ selector of type ‘unsigned char:2’ is
> not compatible with any association
>   #define type_to_str(__x) _Generic((__x), \
>                                     ^
> test.c:17:18: note: in expansion of macro ‘type_to_str’
>     printf("%s\n", type_to_str(b.f1));
>                    ^
> Makefile:7: recipe for target 'test.o' failed
> make: *** [test.o] Error 1
> bash: ./test: No such file or directory
>
>
> The test program is:
>
> $ cat test.c
> #include <stdio.h>
>
> struct bits {
>    unsigned char f0;
>    unsigned char f1:2;
> };
>
> #define type_to_str(__x) _Generic((__x), \
>    unsigned char : "unsigned char")
>
> int main(void) {
>    struct bits b = { .f0 = 255, .f1 = 3 };
>
>    printf("%d\n", b.f0);
>    printf("%s\n", type_to_str(b.f0));
>    printf("%d\n", b.f1);
>    printf("%s\n", type_to_str(b.f1));
>
>    return 0;
> }
>
...
> How do I create a type association for a bit field?

I suspect this falls under the set of issues that fall under bug
65471 - type interpretation in _Generic.  The C language rules
for _Generic aren't completely clear about what conversions are
to take place.  It would be helpful if you could your test case
to the bug to make sure the bitfield case is considered when
the issue is discussed by the C committee.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65471

The only idea for a workaround that comes to mind is to trick GCC
into forgetting that it's a bit-field.  This hack seems to work:

   #define type_to_str(__x) _Generic((0)?(__x):(__x), \

Martin



More information about the Gcc mailing list