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

See comment on (c) below

On Wed, Feb 24, 2016 at 1:53 PM Joseph Myers <> wrote:
> On Wed, 24 Feb 2016, Martin Sebor wrote:
> > > 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.
> >
> > Unfortunately, the + n trick is far too limited to be generally
> > usable.  Since GCC allows bit-fields of other integers types
> > besides those described by the standard (e.g., long long), the
> > plus expression would have to be converted to the widest possible
> > type (e.g., by (x + 0LL)) which would defeat the purpose of
> > _Generic.  The trick of course work at all for type-generic
> > macro intended to also accept non- scalar arguments.
> There are lots of variants of the trick (including the conditional
> expression one), depending on which types you care about distinguishing
> and which are valid arguments to the macro.  If you want, you can even
> distinguish each bit-field width wider than int individually using typeof,
> via writing expressions with typeof to determine the width of the type.
> I suspect many attempts to use _Generic with non-arithmetic types would
> run into usability problems in practice because every expression in the
> generic association list must still pass the Constraints whatever the type
> of the controlling expression - so you can select a function name based on
> that type, but putting more complicated expressions directly inside
> _Generic would be problematic in many cases if a wide range of types is to
> be allowed.
> There is a basic question: is _Generic supposed to be arbitrarily
> expressive, or is it meant to cover cases like <tgmath.h>?  The answer in
> the context of questions about qualifiers and array-to-pointer decay was
> that it is meant to cover cases like <tgmath.h>, not to be arbitrarily
> expressive for hypothetical cases.  Maximal expressiveness would allow
> distinguishing all bit-field widths, but that would fall down on
> usability.
> Integer types narrower than int are effectively second-class entities in
> C; you can't write constants of those types, for example, and they get
> promoted before used in arithmetic or being passed in variable arguments;
> while you *can* select on them with _Generic, the utility of doing so may
> be limited.  Bit-fields are effectively third-class entities, and
> bit-fields with implementation-defined declared types other than int or
> signed int or unsigned int are fourth-class (not required by the standard
> at all, and have their own problems of specification - and the final
> choice for DR#315 was to leave pretty much everything about such
> bit-fields implementation-defined - see the minutes for Portland 2006,
> London 2007, Kona 2007).
> > GCC's handling of bit-fields in __typeof__  is also a problem
> > and causes bugs in <tgmath.h>.  For example, the following is
> > rejected by GCC (with not just one but 42 errors) as a result:
> >
> >   struct S { unsigned b: 31; } s;
> >   carg (s.b);
> That should be reported as an ordinary bug in <tgmath.h>, that can easily
> be addressed by using unary + so that typeof isn't applied to a bit-field
> (<tgmath.h> treats all integer types the same and non-arithmetic types are
> irrelevant to it, so unary + is absoletely fine there).
> > If it isn't clear it should be brought up in WG14 and clarified.
> > It's clear enough in C++ for bit-fields to be used as arguments
> > to overloaded functions or function templates.  I can't imagine
> C++ has long diverged from C regarding bit-fields (allowing other declared
> types, allowing widths wider than the width of the underlying type, now
> requiring plain int bit-fields to be signed, ...).  Whereas C has its line
> of textual history going back to various C90 DRs and showing that:
> (a) whether a bit-field width counts of part of the type doesn't generally
> matter within the standard except for integer promotions, so can safely be
> left unspecified with just special wording for promotions (modulo the new
> _Generic issue);
> (b) everything about such matters for bit-fields of nonstandard types can
> be left implementation-defined;
> (c) nothing defines semantics of conversion of out-of-range values to
> bit-fields other than treating the width as part of the type (or in the
> case of _Bool bit-fields, having the special wording to make it explicit
> that those have the semantics of _Bool not the semantics of an ordinary
> unsigned integer type with the specified number of bits).

I don't see where in the standard it says the width of a bit field is
part of the type.
I see In Section paragraphs 9, 10, 11, 12 requires the compiler to know
the width, but I don't see where the width is part of the type.

Could you point me to the appropriate paragraph(s)?

-- wink

> --
> Joseph S. Myers

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