See comment on (c) below On Wed, Feb 24, 2016 at 1:53 PM Joseph Myers <jos...@codesourcery.com> 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 6.7.2.1 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 > jos...@codesourcery.com