3 ms·
"Let’s consider a trivial example: struct { int a; time_t b; int c; }; With 32-bit time_t, the offset of c is 8. With the 64-bit type, i
by mhandley 2y ago
"Let’s consider a trivial example:
struct {
int a;
time_t b;
int c;
};
With 32-bit time_t, the offset of c is 8. With the 64-bit type, it’s 12."
Surely it's 16 not 12, as b needs to be 64-bit aligned, so padding is added between a and b? Which also kind of makes the point the author is trying to make stronger.
- AshamedCaptain 2y agoMost x86 ABIs do not mandate padding for 64-bit types, due to the lack of 64-bit loads (at the time).
- 256_ 2y agoI thought you were right, but I tested it on x86_64 GNU/Linux with this struct: struct ts { int32_t dword1; int64_t qword1; int32_t dword2; }; Writing -1 to all 3 members and printing out the individual bytes up to sizeof(struct ts), it produces this with -O0 and -O3: FF FF FF FF 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 With -Os, I get some garbage data after the last member (always those 2 byte positions, with different values every time): FF FF FF FF 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF 45 76 00 00 I feel like I'm missing something obvious here. Or maybe my system's ABI is a weird exception.
- jabl 2y agoWas this with x86_64? The point of the parent was about x86_32, I believe.
- AshamedCaptain 2y agoIn addition to the confusion about x86 and x86_64/amd64, you should also know that -O[s123] cannot possibly influence the padding of structures, or it would mean you could not link a library compiled with -Os with a program compiled with -O3 (or viceversa).
- account42 2y agoIn theory the compiler could change the padding of structures if it can prove that this never leaks out of the translation unit. Of course, printing the size or bits of the structure would inhibit that.
- EdSchouten 2y agoExactly. This is also highly problematic if you try to perform atomic operations against bare 64 bit integers on those systems, because the atomic instructions do require them to be 8 byte aligned. In C11 and later it’s not an issue, because _Atomic(int64_t)’s alignment may be stricter than int64_t. This was also an issue in Go, because it tries to use the same alignment rules as C to make cgo work. There they also solved it by adding dedicated atomic types. https://github.com/golang/go/discussions/47141 https://github.com/golang/go/discussions/47141