I am trying to define a union struct with some struct and primitive members overlapping in memory with a simple array. This works perfectly in Clang and MSVC, but it doesn't compile with GCC (G++).
struct Vector3 {
float x;
float y;
float z;
Vector3() {}
};
struct Plane {
union {
struct {
Vector3 normal;
float d;
};
float elements[4] = { 0 };
};
Plane() {}
};
With GCC, I get this compile error:
<source>:11:33: error: member 'Vector3 Plane::<unnamed union>::<unnamed struct>::normal' with constructor not allowed in anonymous aggregate
11 | Vector3 normal;
| ^~~~~~
Is the code example I gave valid C++? Why specifically is it not allowed in an anonymous aggregate, but it seems to work in a named one? What can I change about it to make it work in GCC that doesn't involve deleting the constructors or naming the struct in the union? What is the reason that it works in Clang and MSVC but not in GCC?
Is there a way to make it work if I replace struct {
with struct Named {
?
struct {...};
with neither a type name nor a list of variables after it). – Saxenfloat elements[4] = { 0 };
only init the first element. I believe that is not what you want! – ChaunceVector
's ctor, it's useless. FYI what you are trying to do is UB, you cannot type pune between struct and an array - accessing inactive members of union which do not share to common initial sequence is UB. – Adamsen0
in the braces can be omitted. – Heracliteanism0
is omitted, all values are initialized todefault
which is 0, right! But if you give an argument, it is passed in order to the elements. If only one is present, only one is set. Simply try it out with any other value as0
to see the effect! – ChaunceIf only one is present, only one is set.
And the rest are value initialised.{ 0 }
is confusing and I would recommend against it, but has the same end result as{}
or{0,0,0,0}
in this case. – Autolysis