Anonymous union/struct of class with constructor
Asked Answered
M

2

6

GCC complains about this code even though I compile with -std=c++11 flag, and my gcc version supposedly supports Unrestricted unions (>4.6).

union 
{
    struct 
    {
        float4 I,J,K,T;
    };
    struct 
    {
        float4 m_lines[4];
    };
    struct
    {
        float m16f[16];
    };
    struct 
    {
        float m44f[4][4];
    };
};

Note that float4 has a non-default constructor that takes 0 parameters.

class float4 
{   
    public:
       float4();
 ....
};

Any idea of what I could do ? The error is :

<anonymous union>::<anonymous struct>::I’ with constructor not allowed in anonymous aggregate
Microwave answered 11/3, 2012 at 12:4 Comment(7)
Remove the constructor from your float4 class.Everrs
@KerrekSB: Well, no, I can’t :)Microwave
c++ has no anonymous structs... it is an extension of your compilerKenney
@JohannesSchaub-litb: Good catch. I confused it with C11, which does allow anonymous structs. I should retract my comment.Everrs
Why did you feel the need to nest these floats inside nonstandard anonymous structs in the first place? I can't think of any benefit to this. However, of course, maybe I've just overlooked it.Darned
@underscore_d: I think the idea was to access the inner object without naming it, so if I instantiate an object obj which type is the union of all those anonymous struct, I could do something like b = obj.I. However had I named the struct I would have had to do b = obj.foo.I. I was porting a very large codebase to gcc, from a compiler which accepted this syntax and refactoring the whole code was too expensive.Microwave
Yeah, at the time of commenting, I had overlooked the fact that your first struct declares multiple floats, so you couldn't just move all your struct.float members out into the top level of the union. It seems your structs were achieving some purpose there, albeit a confusing one. ;)Darned
C
0

The issue here is not the fact that your class float4 has a constructor, making it a non-POD under the old C++03 definition of POD. Rather, the issue is that your union and the structs within your union are anonymous. If you simply name them, it will work:

union u
{
    struct s1
    {
        float4 I,J,K,T;
    };
    struct s2
    {
        float4 m_lines[4];
    };
    struct s3
    {
        float m16f[16];
    };
    struct s4
    {
        float m44f[4][4];
    };
};
Charbonnier answered 11/3, 2012 at 12:22 Comment(4)
"it will work". what is the desired goal? you have created an empty union. i doubt that this was desired though.Kenney
Thanks for the solution, but I would like to keep my anonymous structs: this union is nested inside a class and if I change the names, I would have to rename every single call. This code works fine on MSVC10, I wish I could tweak gcc into treating it correctly too.Microwave
@qdii, the problem is that anonymous structs are not valid C++, so you'll run into compiler issues like this all the time if you try to write cross-platform code using them. It would serve you better to avoid using anonymous structs entirely.Charbonnier
For anyone reading, this new union has no data members, just 4 inner type definitions that are unused. To get functionality back, declare members with those inner types, including between the closing brace and the semicolon. But float4 has a non-trivial default constructor, which gives one to s1 and s2, which gives u a deleted default constructor (if a non-static member of either struct is made).Cornett
R
-3
union // This do not need named, it will same to MSVC10 or XCode
{
    struct s1
    {
        float4 I,J,K,T;
    };
    struct s2
    {
        float4 m_lines[4];
    };
    struct s3
    {
        float m16f[16];
    };
    struct s4
    {
        float m44f[4][4];
    };
};
Rosewater answered 14/6, 2018 at 2:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.