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?
a
includes one extra 4-byte block for the array for make S2 16 bytes? Possibly related: #17091882 – Undefinedalignas(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. – Toggerychar[8]
, Could you please replace, inS2
:alignas(uint64_t) char a[8];
with another 64 bits type, like for example adouble
? – Smashandgrabalignof(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. – Toggery