N 2774: unsigned long and unsigned long long bit-fields

Submitter: Philipp Klaus Krause
Submission Date: 2021-07-09

Summary:

unsigned long and unsigned long long bit-fields.

This adds unsigned long and unsigned long long to the required supported types for bit-fields.

Justification:

C currently mandates support for bool, int, signed int and unsigned int as types for bit-fields. Support for further types is implementation-defined. However, larger bit-fields are useful and having them supported in the standard would be good. Most useful would be types larger than int (since these add functionality that is currently not mandated by the standard).

Such types are supported by many implementations, including IAR, GCC and clang. They are widely used.

Debian code search shows that in particular, unsigned long and unsigned long long are very widely used, in different programs (including e.g. GCC and Linux)

It is also relatively clear how to implement support for unsigned long and unsigned long long. For other types there would be further questions (e.g. should 1-bit bit-fields be allowed for signed long? Should it be implementation-defined if a long bit-field is signed? Should support for types other than the standard types (e.g. bit-precise, extended) be required?). So this proposal focuses on the two easiest and most useful types.

What is the type of a "bit-field of type unsigned int" (quote from current standard draft N2596)? There is implementation divergence. clang considers it to be 'unsigned int'. GCC considers it to be 'bit-field of type unsigned int of specified width'. Thus in _Generic it will match unsigned int for clang, but not GCC. This proposal does not try to resolve this divergence. But the new types are also affected by it. E.g. when left-shifting a bit-field of type unsigned long, the uppermost bits of the result can be 0 for GCC when they are 1 for clang (if bits are shifted into bits that are still within the width of unsigned long, but outside the width of the bit-field); a narrow bit-field of type unsigned long when used as an operand promotes to int in GCC, but is unsigned long in clang.

Do we want to require support of bit-fields of type unsigned long and unsigned long long?

Proposed changes (vs N2596):
In 6.7.2.1p5, replace
"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."
by
"A bit-field shall have a type that is a qualified or unqualified version of _Bool , signed int, unsigned int, unsigned long, unsigned long long or some other implementation-defined type.".
In J.3.9, replace
"Allowable bit-field types other than _Bool, signed int, and unsigned int"
by
"Allowable bit-field types other than _Bool, signed int, unsigned int, unsigned long, unsigned long long".
In J.5.8 replace
"A bit-field may be declared with a type other than _Bool, unsigned int, or signed int"
by
"A bit-field may be declared with a type other than _Bool, unsigned int, signed int, unsigned long or unsigned long long".

Does WG14 want to see a proposal for further standard integer types along the lines of this one?

Does WG14 want to see a proposal for bit-precise integer types along the lines of this one?