12

I am trying to statically initialize the following structure in Visual Studio 2010:

struct Data
{
   int x;
   union
   {
      const Data* data;
      struct {int x; int y; };
   };
};

The following is fails with error C2440: 'initializing' : cannot convert from 'Data *' to 'char'.

static Data d1;
static Data d = {1, &d1};
static Data d2 = {1, {1, 2}};

I have found references to some ways this can be initialized properly but none of them work in VS2010. Any ideas?

4 Answers 4

24

ISO C++03 8.5.1[dcl.init.aggr]/15:

When a union is initialized with a brace-enclosed initializer, the braces shall only contain an initializer for the first member of the union. [Example:

union u { int a; char* b; };
u a = { 1 };
u b = a;
u c = 1; // error
u d = { 0, "asdf" }; // error
u e = { "asdf" }; // error

—end example]

So, generally speaking, it can't be done.

Sign up to request clarification or add additional context in comments.

Comments

5

Can you do it by defining overloaded constructors? Untested code ahead:

struct Data 
{ 
    int x; 
    union 
    { 
        const Data* data; 
        struct {int a; int b; } z; 
    } y;

    Data()
    {
        x = 0;
        y.data = 0;
        y.z.a = 0;
        y.z.b = 0;
    }

    Data(int x_, Data* data_)
    {
        x = x_;
        y.data = data_;
    }

    Data(int x_, int a_, int b_)
    {
        x = x_;
        y.z.a = a_;
        y.z.b = b_;
    }
}; 

static Data d1; 
static Data d(1, &d1); 
static Data d2(1, 1, 2); 

Comments

3

Change it to:

struct Data
{
   int x;
   union
   {
      const Data* data;
      char ch;
   };
};

static Data d1;
static Data d = {1, &d1};

2 Comments

Indeed that works, but I have oversimplified my real-life case so now I have updated the question with a better code which fails for d2 initialization.
I imagine it's not apparent to newcomers why this is supposed to work. I always add a small explanation to my answers of this kind.
1

You can make this work if all your union types are pointers, by using a void pointer as the first element of the union. All pointers can be converted to a void pointer, so your union can be initialized with an arbitrary pointer type. For the given example, you get:

struct Data
{
   int x;
   union
   {
      const void* unused;
      const Data* data;
      struct {int x; int y; }*; //Not sure this works written like this
      const char* asChar;
      const int*  asInt;
   };
};

static Data d1;
static Data d2 = {2, &d1};
static Data d3 = {1, "Hello, world!"};

The other possibility is to do this in C instead. In C you can specify which part of the union is initialized. Using your original struct (and giving your structure the name asStruct):

static Data d1;
static Data d2 = {2, &d1};
static Data d3 = {3, {.asStruct = {0,0}}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.