This is the mail archive of the 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: How to use _Generic with bit-fields

On Mon, 22 Feb 2016, Martin Sebor wrote:

> for the C standard not to support it.  (The problem is simply that
> wording that specifies the feature was poorly chosen and GCC seems
> to follow it a bit too strictly, and to the detriment of usability.)

The wording for bit-fields, although unclear in places, elegantly 
addresses all the issues with what the semantics of assignment to 
bit-fields are (including e.g. allowing an instruction for conversion of 
floating-point to 16-bit integer, complete with raising exceptions for 
out-of-range values, to be used to convert to int:16, rather than 
requiring a conversion to int and subsequent conversion from int to 
int:16), with none of the duplication that would be involved if bit-fields 
had the underlying types and so semantics for conversions needed to be 
specified separately.  It also naturally means that e.g. unsigned long:1 
promotes to int in expressions, by the normal rules for promotions.

> $ cat z.c && /home/msebor/build/gcc-trunk-svn/gcc/xgcc
> -B/home/msebor/build/gcc-trunk-svn/gcc -Wall -Wextra -Wpedantic -xc z.c
> struct S { unsigned i: 31; } s;
> int i = _Generic (s.i, unsigned: 1);
> z.c:2:19: error: â_Genericâ selector of type âunsigned int:31â is not
> compatible with any association
>  int i = _Generic (s.i, unsigned: 1);
>                    ^

That can be avoided simply by using unary + in the controlling expression 
of _Generic (just as using unary + will avoid an error from sizeof, if you 
want to be able to apply that to expressions that might be bit-fields) - 
or any of the other techniques for achieving promotions of selected types.

You can't use bit-fields with sizeof, or with unary &, or in GNU C with 
typeof.  I think extending this constraint to _Generic - meaning you need 
to use a trick such as unary + when a bit-field might occur there - is 
consistent with the peculiar position of bit-fields in C as not quite 
normal objects or types (and consistent with how _Generic is intended for 
certain limited kinds of overloading such as <tgmath.h>, not for 
arbitrarily expressive logic on types, cf. the rejection of overloading on 
qualifiers).  If someone uses e.g. unsigned int:8 as the controlling 
expression of _Generic, it's hardly clear whether a selection for unsigned 
char (a type with the same set of values), unsigned int (the declared type 
ignoring width) or int (the type resulting from the integer promotions) 
would be the most useful selection.

Joseph S. Myers

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