Bit fields in C/C++ code are mostly used to map existing hardware registers and the field positions within them [citation needed].
For the following example hypothetical device, please assume the following:
typedef unsigned B;
typedef unsigned U;
struct S {
bool f1 : 1; // Explicitly bool
B f2 : 1; // I’ll be changing B, once, later
// U : 7; // Line “Optional 7” – designed to change the size of S to >8 bits
// U : 15; // Line “Optional 15” – designed to change the size of S to >16 bits
// U : 0; // Line “Optional 0” – the ultimate purpose of this proposal
}; // S
/* Insert whatever linker-specific magic is required to get this to a particular address… */
volatile S s;
Two major compilers have been used to guide this submission: clang and gcc. Both have been targeted at both ARM and x86-64. Both do what is described below for both.
Note that gcc has the flag `-fstrict-volatile-bitfields` set, to enforce access to the “underlying type” (Note that a request to determine exactly what that means has been submitted…)
ASIDE: To me, the above examples highlight a deficiency with the standard, such that defining surrounding bit fields shouldn’t be permitted to determine the access requirements of the current bit field. In my opinion, the standard should explicitly enforce the compiler to access the “underlying type” of the field, suitably aligned to the requirements of the location – but I understand that this is not a good idea, considering that existing code indiscriminately uses “int” for bit fields.
I propose a change to the wording in the standard. To paraphrase, the presence of a “: 0” bitfield suggests “align the NEXT field with the next alignment boundary”. I propose that this should read "pad the CURRENT struct to the next alignment boundary for this CURRENT field's type”.
ASIDE: Note the repetition of “CURRENT” – to my reading, the existing standard potentially leaves undetermined whether the alignment should be the responsibility of the current padding field or the new field…
This has two advantages: