Why is the compiler forbidden (by the standard) from reordering the struct?
The basic reason is: for compatibility with C.
Remember that C is, originally, a high-level assembly language. It is quite common in C to view memory (network packets, …) by reinterpreting the bytes as a specific struct
.
This has led to multiple features relying on this property:
-
C guaranteed that the address of a
struct
and the address of its first data member are one and the same, so C++ does too (in the absence ofvirtual
inheritance/methods). -
C guaranteed that if you have two
struct
A
andB
and both start with a data memberchar
followed by a data memberint
(and whatever after), then when you put them in aunion
you can write theB
member and read thechar
andint
through itsA
member, so C++ does too: Standard Layout.
The latter is extremely broad, and completely prevents any re-ordering of data members for most struct
(or class
).
Note that the Standard does allow some re-ordering: since C did not have the concept of access control, C++ specifies that the relative order of two data members with a different access control specifier is unspecified.
As far as I know, no compiler attempts to take advantage of it; but they could in theory.
Outside of C++, languages such as Rust allow compilers to re-order fields and the main Rust compiler (rustc) does so by default. Only historical decisions and a strong desire for backward compatibility prevent C++ from doing so.