N2945: bit-precise bit-fields

Submitter: Philipp Klaus Krause
Submission Date: 2022-03-10

Summary:

Bit-fields of unsigned bit-precise integer types. This is a follow-up proposal to N2774.

This mandates support for bit-fields of unsigned bit-precise integer types.

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, other bit-fields are useful and having them supported in the standard would be good. Particularly useful would be types larger than int (since these add functionality that is currently not mandated by the standard).

Some such types (e.g. unsigned long, unsigned long long) 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)

N2774 proposed support for unsigned long and unsigned long long. When N2774 was discussed, WG14 wanted bit-fields of unsigned bit-precise integer types instead. Since the stadnard requires that implementations support bit-precise types up to the width of long long, this should also cover many current use-cases of bit-fields of type unsigned long and unsigned long long.

Bit-precise integer types allow programmers to explicitly state their intent on how many bits are needed; but since they are addressable, they need padding bits when their width is not a multiple of CHAR_WIDTH. Some implementations might use more padding for alignment. Where there is a need to save memory, they are thus not suitable. Using bit-precise integer types in bit-fields solves this issue.

Bit-precise integer types are not promoted to int, as other types smaller than int are; thus bit-fields of bit-precise unsigned integer types are not affected by issues that affect some other bit-fields.

While signed bit-precise bit-fields are left as an implementation extension, for integer promotions we nevertheless propose wording that applies to all bit-fields of bit-precise types, to avoid implementation divergence.

Do we want to bit-precise bit-fields?

Proposed changes (vs N2732 with N2763 applied):
In 6.3.1.1p2, replace
"If the original type is not a bit-precise integer type (6.2.5) and if an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int;"
by
"The value from a bit-field of a bit-precise integer type is converted to the corresponding bit-precise type. If the original type is not a bit-precise integer type (6.2.5) and if an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int;"
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, a bit-precise unsigned integer type, 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, and bit-precise unsigned integer types".
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, or a bit-precise unsigned integer type".

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