I've been told:
[ABIs] guarantee the exact layout of the struct, byte offset of every member, which bits are used for bit fields, where and how much padding there is, etc...
But I've always believed that padding and alignment were unspecified and unreliable.
Does the Itanium ABI (which GCC uses) in fact specify these things (as far as I can tell, it doesn't appear to beyond specifying ranges)?
And if it does, how do options like __attribute__ ((packed))
fit into that? Do they ultimately break the ABI by altering the alignment of things?
Or, as the quotee implies, is packing merely unspecified between toolchains but in fact reliable and predictable within the use of a certain ABI? And then, again, how does something like __attribute__ ((packed))
fit into that?
padding and alignment are unspecified by the ISO standard C++ specification and hence unreliable.
The use of the word "exact" in the quote is exaggeration. The Itanium ABI (which GCC uses) may specify these things (as within specifying ranges) as needed rather than always and exact ly.
Packing is in fact reliable and predictable within the use of toolchains assuming predetermined target architecture & environment- viz. ABI. When all target specific details applicable to the tool-chain are predetermined __attribute__ ((packed))
like any other construct will generate output predictably for the tool-chain to work correctly.
You need to follow the documentation to the standards incorporated by reference.
Most types' size and alignment is specified in the Intel System V ABI specifications; for example, long long
and long double
types' size and alignment are documented in the Unix System V Application Binary Interface, Itanium Processor Supplement (no. 245370-001), table 3-1 Additional Fundamental Data Types.
It's a little difficult to find authoritative copies of standards, especially as there isn't a real standards process. A good reference that includes the sizes and alignments of all types in the LP64 ABI is http://www.x86-64.org/documentation/abi.pdf although it doesn't cover the ILP32 ABI.
__attribute__((packed))
is of course gcc-specific, as is #pragma pack
for MSVC. You may be able to use compiler compatibility features to get consistent layout of structs across compilers, but assuming that behavior is the same just because a compatibility feature is implemented is not a good idea; you should test that sizes and key offsets are the same.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With