https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93209
Bug ID: 93209 Summary: What is a bitfield's "underlying type"? Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: John.Adriaan at BigPond dot com Target Milestone: --- For the following, please assume: A. `sizeof(bool)` equals `1`; B. `sizeof(unsigned)` equals `4`; C. `-fstrict-volatile-bitfields` is ON; D. The compiler target is _irrelevant_ - both ARM and x86-64 exhibit this. With the following code: struct S { bool b : 1; unsigned i : 1; // unsigned : 7; // Padding > 8 bits // unsigned : 15; // Padding >16 bits }; // S static volatile S s; int main() { s.b = true; s.i = 1; return sizeof(S); } // main() `main()` always returns 4. It's a (padded) struct, so OK. Looking at the compiled op-codes: 1. The access to `s.b` is by byte. 2. The access to `s.i` is by byte. I then un-commented the "Padding > 8 bits" line: 3. The access to `s.b` is by byte. 4. The access to `s.i` is by half-word/WORD. I then re-commented the above, and un-commented the "Padding >16 bits" line: 5. The access to `s.b` is by byte. 6. The access to `s.i` is by word/DWORD. Note that in each version, the type of `s.i` has not changed: it's always `unsigned`. The difference is obvious - the compiler chooses the MINIMUM of: a. The smallest representation of the field's type; b. The smallest representation of the `struct`. In other words, the documentation for `-fstrict-volatile-bitfields` that contains the reference to "underlying type" isn't clear whether that's the declared type of the field, or the ultimate (UN-padded) size of the `struct`. I personally feel that this is a bug: the compiler should heed the declared type of the field, not some derivative of the ultimate `struct` size. This is of course also exacerbated by the current issue with bug 51242.