also, if performance is critical to you, profile stuff and compare outputted assembly, more often than not you'll find that llvm just outputs the same thing in both cases
also, if performance is critical to you, profile stuff and compare outputted assembly, more often than not you'll find that llvm just outputs the same thing in both cases
See "6.7.3.2 Structure and union specifiers", paragraph 16 & 17:
> Each non-bit-field member of a structure or union object is aligned in an implementation-defined manner appropriate to its type.
> Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared.
> Each non-bit-field member of a structure or union object is aligned in an implementation-defined manner appropriate to its type.
But, I still don't think that what you've said is true. This is because alignment isn't decided per-object, but per type. That bit is covered more fully in 6.2.8 Alignment of objects.
You also have to be able to take a pointer to a (non-bitfield) member, and those pointers must be aligned. This is also why __attribute__((packed)) and such are non-standard extensions.
Then again: I have not passed the C specification lawyer bar, so it is possible that I am wrong here. I'm just an armchair lawyer. :)
(but for padding, yes, that's correct.)
[1] https://open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdf section 6.7.3.2, paragraph 17.
It's part of the ABI spec. It's true that C evolved in an ad hoc way and so the formal rigor got spread around to a bunch of different stakeholders. It's not true that C is a lawless wasteland where all behavior is subject to capricious and random whims, which is an attitude I see a lot in some communities.
People write low level software to deal with memory layout and alignment every day in C, have for fourty years, and aren't stopping any time soon.