Okay, I tried this code :
Code:
#include <iostream>
#include <cassert>
struct point
{
union
{
struct
{
float x, y, z;
};
float p[3];
};
point(float a, float b, float c)
{
x = a;
y = b;
z = c;
assert(&x == p + 0);
assert(&y == p + 1);
assert(&z == p + 2);
};
};
int main(void)
{
std::cout << sizeof(point) << std::endl;
point test(1, 2, 3);
std::cout << test.x << ", " << test.y << ", " << test.z << std::endl;
std::cout << test.p[0] << ", " << test.p[1] << ", " << test.p[2] << std::endl;
return 0;
}
compiled with :
Code:
g++ -std=c++11 -Wall -Wextra -pedantic -O3
There is an ISO warning about anonymity but yolo.
However, the code seems to work and will crash should the struct not be aligned. From what I could google about this, I found someone on StackOverflow that said,
C++ guarantees that elements of an array are laid out contiguously, but only guarantees that the address of an element of a POD struct is greater than the address of all earlier-declared elements (i.e. there is more flexibility in laying out structs).
In this case, there is no padding because the sizeof(point) is 12. Or rather, g++ does not pad because 12 is a sum of powers of 2 (8 + 4). So because of that and C++'s guarantee, the alignment is held properly... in this case. It's because if &y must be > &x and &z must be > &y and there's only 12 bytes of room we can safely use this to establish that the memory really is laid out in order.
Also, I think this would change if the array was larger. The union is the size of its largest member and if it was say 4 then the guarantee still holds but y and z may not necessarily have 0 spacing between them. As in, the struct could be laid out as x, y, gap, z or x, gap, y, z. We'd hope for x, y, z, gap but that's not guaranteed.
Is this right?
It seems like ensuring the the size of the anonymous structure being the same as the array is key here. And that the structure itself (or in this case, class) is natively aligned and receives no padding from the compiler, for example to 16 bytes or something like that.