Oleksandr
Oleksandr

Reputation: 449

Why inherited struct members are inaccessible in union?

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

Answers (1)

Bartek Banachewicz
Bartek Banachewicz

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

Related Questions