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]

C pre-DR#9: implementation-defined bit-field types


This pre-DR discusses two issues with the support for 
implementation-defined bit-field types which was added in C99, one 
relevant to when they can be unsigned (as was e.g. discussed in bug 17211 
- relevant to -funsigned-bitfields, and potentially should it be decided 
for any target that following the target's standard dialect with such 
bit-fields is more important than default GNU C portability to that 
target), and one dealing with the peculiarities of wider-than-int 
bit-fields.

At present GCC sort-of supports such bit-fields: they are treated as a GNU 
C extension and diagnosed with -pedantic.  It might make sense to document 
them as implementation-defined bit-field types in C99 mode (and so not 
pedwarn when pedantic in C99 mode), but it seems desirable to try to 
resolve these issues, especially the one of signedness, first.

(Incidentally, -funsigned-char -fsigned-bitfields will leave plain char 
bit-fields as unsigned.  I'm inclined to think this is a bug, and 
-fsigned-bitfields should make char bit-fields signed, although the 
signed-bitfields default with no actual command-line option should leave 
them with whatever signedness char has.  There's even 
explicit_flag_signed_bitfields which is set but never used and which would 
be natural for this purpose - it used to be used with -traditional only.)

Pre-DR: implementation-defined bit-field types
==============================================

C99 6.7.2#2 lists the valid combinations of type specifiers.  6.7.2#5
says:

       [#5]  Each  of  the comma-separated sets designates the same
       type, except that  for  bit-fields,  it  is  implementation-
       defined  whether  the specifier int designates the same type
       as signed int or the same type as unsigned int.

6.7.2.1#4 says:

       [#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.

1. Suppose an implementation supports bit-fields of types char, short,
long and long long.  Bit-fields of type int may be unsigned on that
implementation.  Must bit-fields of type char nevertheless have the
same signedness as ordinary objects of type char, and similarly for
those of types short (or short int), long (or long int), long long (or
long long int)?  The practice in C++ is that all these are
implementation-defined (except that C++ does not include long long);
it seems an oversight in the addition of implementation-defined
bit-field types in C99 not to make such provision for char, short,
long and long long bit-fields as is made for int bit-fields.  (It
might still be appropriate to ensure, for example, that short and
short int have the same signedness as bit-field types, although that
might be unsigned and so differ from the signedness of signed short
and signed short int.)  Footnote 104, reiterating that int as a
bit-field type may be signed or unsigned, would also need amendment.

2. Suppose an implementation has 32-bit int (with no padding bits) and
permits unsigned long long as an implementation-defined bit-field
type.  Consider the code:

  struct s { unsigned long long a : 37, b : 37; } x;
  // ...
  sizeof(x.a + x.b);

x.a and x.b have 37-bit unsigned integer types, by 6.7.2.1#9.  Such
types have an integer conversion rank greater than that of int, so are
unchanged by the integer promotions.  Whether or not x.a and x.b have
the same 37-bit type, (x.a + x.b) also has a 37-bit unsigned integer
type.  However, (x.a + x.b) does not designate a bit-field member, so
it does not violate the constraints on sizeof.  But what should
sizeof(x.a + x.b) evaluate to, when (x.a + x.b) has such a bit-field
type which does not occupy an integer number of bytes?  Must an
implementation define representations occupying an integer number of
bytes (with some padding bits) for all such types, although such
representations would have no use other than to define the result of
sizeof?

Changing the promotion rules for bit-fields wider than int to avoid
such expressions of bit-field type would create an odd inconsistency
in the type system about which types are promoted, although it would
be consistent with C++ where bit-fields have narrow representation but
are considered to have the declared type rather than a special narrow
type; changing the C definition of bit-field types to follow the C++
one would be more radical and probably not suitable for a TC.  (C++
then has a special rule so that unsigned int bit-fields promote to int
if narrower than int.)  The alternative is to be more explicit about
the nature of bit-field types and to define when an expression has
such a type, and to make the constraint on sizeof apply to expressions
with such types and not just to bit-fields themselves.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
  http://www.srcf.ucam.org/~jsm28/gcc/#c90status - status of C90 for GCC 4.0
    jsm@polyomino.org.uk (personal mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)


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