I am getting unexpected results when running the following code for 32-bit x86 linux (compiler flags: g++ -std=c++14 -m32). I tried gcc and clang.
#include <iostream> using namespace std; struct S1 { uint64_t a; uint32_t b; }; struct S2 { alignas(uint64_t) char a[8]; uint32_t b; }; int main() { cout << "sizeof(S1)=" << sizeof(S1) << endl; cout << "sizeof(S2)=" << sizeof(S2) << endl; } The output is:
sizeof(S1)=12 sizeof(S2)=16 What is happening here? Why are S1 and S2 of different size? As I understand it, 64 bit integer values are aligned to 32 bit on 32-bit x86 machines. This does explain why the size of S1 is 12 bytes. But why does this not apply to S2?
aincludes one extra 4-byte block for the array for make S2 16 bytes? Possibly related: stackoverflow.com/questions/17091382/…alignas(uint64_t)is defined as the same asalignas(alignof(uint64_t)). If you addcout << alignof(uint64_t) << endl ;to the example you'll get an output of 8 (gcc at least). So the question should be 'why does gcc think alignof(uint64_t) is 8 when it's 4 on the platform in question. NB: It has to be 4 because sizeof(S1) is 12.char[8], Could you please replace, inS2:alignas(uint64_t) char a[8];with another 64 bits type, like for example adouble?alignof(double)is typically 8 anyway. Sosizeof(S2)would be 16 without the alignas(uint64_t). As I mentioned gcc says alignof(uint64_t) is 8. That appears to be the root of the problem.