Reputation: 449
I have following code which generates error at compile time:
struct s { int three; };
union alias {
struct { int one; };
struct { int two; };
struct : s {};
};
int main()
{
alias a;
a.one = 1; // OK
a.two = 2; // OK
a.three = 3; // error: 'union alias' has no member named 'three'
return 0;
}
For some reason members of inherited struct in the union are inaccessible. The main purpose of this code is to provide an aliases to members of struct s
.
Why compiler doesn't see members of inherited structure? Any options to make them accessible?
Upvotes: 1
Views: 229
Reputation: 39390
Okay, after a bit of head-scratching, I think I can explain this correctly. Well, to start things off, this is Illegal As Heck (tm).
A struct
defined within a union confuses the compiler a bit. If a struct def is followed by a name, a new variable of type of such struct would normally be created, but C++ explicitly disallows anonymous structs. If you omit that name, it could mean two things - either an anonymous struct type is created and then immediately dropped (which meets with a -Wpedantic
warning), or, as seems to be happening with GCC, it considers it a creation of an anonymous member of an anonymous type, which is a non-standard extension:
union alias {
struct { int one; }; // anonymous member of an anonymous type
struct a { int two }; // no member, just def of "struct a"
struct { int three; } b; // named (b) member of type anonymous struct
};
All in all, you can't really expect this to work... unless you create the union members with explicit type and data member names:
struct s { int three; };
union alias {
struct A { int one; };
struct B { int two; };
struct C : s { };
A a;
B b;
C c;
};
int main() {
alias a;
a.a.one = 1; // OK
a.b.two = 2; // OK
a.c.three = 3; // OK
}
The whole anonymous union member thing is still a bit puzzling to me, as I can't figure out anything in the standard that would make this work.
Upvotes: 3