Submitter: UK C Panel
Submission Date: 2005-03-04
Source: Joseph Myers <[email protected]>
Reference Document: ISO/IEC WG14
N1103
Version: 1.0
Date: 2005-03-04
Subject: Implementation-defined bit-field types
Summary
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 specifierint
designates the same type assigned int
or the same type asunsigned 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.
Some problems arise with use of an "other implementation-defined type", a new addition in C99.
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. (That all the bit-field types have integer conversion
ranks, and may need to be documented by implementations as extended
integer types, is a consequence of the standard that may not be
intended and may be surprising to some, but it is a logical
consequence of the text of the standard.) 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 and would allow implementations to support bit-fields wider than
int
without needing special support for arithmetic on
such types (alternatively, it could be argued that if an implementor
wishes to support bit-fields wider than int
it is up to
them to implement arithmetic on all bit-field types wider than
int
as a consequence of their decision); 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.
Suggested Technical Corrigendum