Struct Packing
-
Hallo,
folgender Code:
#include <cstddef> //offsetof #pragma pack(push, 8) struct Other { int Offset0; int Offset4; }; struct Test { float Offset0; Other Offset8; }; #pragma pack(pop) int main() { auto s1 = sizeof(Other); //8 auto s2 = sizeof(Test); //C auto x1 = offsetof(Test, Offset0); //0 auto x2 = offsetof(Test, Offset8); //4 return 0; }
Compiler ist VS2015 und erstellt wird ein x64 Projekt. (GCC zeigt das selbe Verhalten.)
Das Problem ist, dass ich Test::Offset8 durch das 8 Byte Packing am Offset 8 erwarten würde und nicht an 4.
Also so und mit einer Größe von 0xF von Test| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | | Offet0 | Offset8 |
Das generierte Layout ist aber
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | | Offet0 | Offset8 |
Kann mir jemand erklären warum das so ist? Ich dachte das pack(8) sorgt dafür, dass nicht "passende" Member mit Padding aufgefüllt werden. Wenn Other 4 Byte groß wäre, würde die struct noch hinter das float passen und nicht gepaddet werden. Da Other aber mit 8 Byte größer als die Lücke ist, sollte Offset8 bei Offset 8 beginnen und nicht bei 4.
-
Ok, eventuell hab ichs raus.
struct Test2 { float x; double y; };
Hier ist y wie erwartet bei 8. Sobald ich Other als
struct alignas(8) Other { int Offset0; int Offset4; };
anlege ist auch beim originalen Snippet das Offset richtig bei 8.
Wird beim originalen Snippet nicht gepaddet, weil Other::Offset0 noch hinter den float passt? Ich hatte erwartet, dass die Other Struktur beim nächsten 8er Offset angelegt wird.