I am porting C99 code to C++(14 or 17), and in many places the list initializer is used. Now I am getting compilation errors and would like to know the simplest way to initalize a union nested by a struct. For instance, the following snippet in C works just fine:
#include <stdint.h>
typedef union Word_t
{
uint32_t word32Bits;
struct
{
uint16_t leastSignificant16Bits;
uint16_t mostSignificant16Bits;
};
} Word_t;
int main()
{
Word_t w1 = (Word_t) {.word32Bits = 0x1234ABCD};
printf("%x\n", w1.word32Bits);
Word_t w2 = (Word_t) {.mostSignificant16Bits = 0x1234, .leastSignificant16Bits = 0xABCD};
printf("%x\n", w2.word32Bits);
return 0;
}
$ gcc test.c --std=c99 -o a && ./a
1234abcd
1234abcd
However, in C++ it does not compile:
#include <stdint.h>
typedef union Word_t
{
uint32_t word32Bits;
struct
{
uint16_t leastSignificant16Bits;
uint16_t mostSignificant16Bits;
} _word16Bits;
} Word_t;
int main()
{
Word_t w1 = (Word_t) {.word32Bits = 0x1234ABCD};
printf("%x\n", w1.word32Bits);
Word_t w2 = (Word_t) {.mostSignificant16Bits = 0x1234, .leastSignificant16Bits = 0xABCD};
printf("%x\n", w2.word32Bits);
return 0;
}
```bash
$ g++ test.c --std=c++14 -o a && ./a
test.c: In function ‘int main()’:
test.c:57:92: error: ‘Word_t’ has no non-static data member named ‘mostSignificant16Bits’
Word_t w2 = (Word_t) {.mostSignificant16Bits = 0x1234, .leastSignificant16Bits = 0xABCD};
The work-araound solution I found is to zero-initalize and then set the internal values of the struct as following:
int main()
{
Word_t w1 = (Word_t) {.word32Bits = 0x1234ABCD};
printf("%x\n", w1.word32Bits);
Word_t w2 = (Word_t) {.mostSignificant16Bits = 0x1234, .leastSignificant16Bits = 0xABCD};
Word_t w2 = {0};
w2._word16Bits = {0x1234, 0xABCD};
return 0;
}
Which works, but it doesn't allow me to explicitly say .mostSignificant16Bits = 0x1234
for instance -- which I think is kind of useful, specially when reading the code.
I tried couple of things like defining static members, creating a user-defined constructor, but still no idea how to simplify the refactor that I am going to do. Ideally, I would like to leave the variable declaration as how it is Word_t w2 = (Word_t) {.mostSignificant16Bits = 0x1234, .leastSignificant16Bits = 0xABCD}
while all the changes are done in the definition of Word_t
.