huaxin
huaxin

Reputation: 31

union inside a struct -- how to do designated initializer?

I have already read struct in union initialize and it does not address my issue

In my legacy code, I have tons of struct-with-union like

typedef struct st 
{
    union
    {
        struct
        {
            uint8    sign ;
            uint8    cells;    
        }s;
        int    data;
    }u;
    int   extra;
} st;

Under C, below compiles:

static const st someval = {
    .sign = 0, .cells ={ 0 },  
    .cells = { 11 }
};

Is there a way to minimally change the compilation method (or code) to make it compiler under g++?

Upvotes: 3

Views: 888

Answers (1)

eerorika
eerorika

Reputation: 238311

static const st someval = {
     .sign = 0, .cells ={ 0 },  
//              ^
     .cells = { 11 } };
//   ^

You initialize cells twice, which makes this ill-formed in C++.

Also, neither sign nor cell are direct members of st. The declaration is ill formed in C as well.

Following would be correct use of designated initializers in C++20 (a future C++ standard which is proposed to introduce designated initializers to the language):

static const st someval = {
     .u{.s{.sign = 0, .cells = 11}},
     // NOTE .extra left zero-initialized
};

or following, which is correct in both C++20 and C:

static const st someval = {
     .u = {.s = {.sign = 0, .cells = 11}},
};

The current C++ standard doesn't have designated initializers however. You can write a function that creates a local non-const zero-initialized st object, then use member accessors to initialize the specific members that you want to initialize, and then return the object. Then you can initialize the const st object with a call to that function. That initialization function might not be useful anywhere else, so you might want to use a lambda to avoid needlessly polluting the namespace.:

static const st someval = []() {
    st o {};
    o.u.s.sign = 0;
    o.u.s.cells = 11;
    return o;
}();

Upvotes: 6

Related Questions