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?
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);
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.
Change it to:
struct Data
{
int x;
union
{
const Data* data;
char ch;
};
};
static Data d1;
static Data d = {1, &d1};
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}}