jeudi 29 septembre 2016

memcpy/memmove to a union member, does this set the 'active' member?

C++ is quite strict about unions - you should read from a member only if that was the last member that was written to:

9.5 Unions [class.union] [[c++11]] In a union, at most one of the non-static data members can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.

Out of curiousity, does this apply only to = assignment, or do memcpy/memmove also have the ability to change the active member?

First, a relatively simple memcpy allowing us to read a uint32_t as an array of uint16_t:

uint32_t u32 = 0x12345678;
uint16_t a16[2];
static_assert(sizeof(u32) == sizeof(a16), "");
std:: memcpy(a16, &u32, sizeof(u32));

But what happens if I make it more complicated with this union:

union {
    double whatever;
    uint16_t a16[2];
} u;
u.whatever = 3.14; // sets the 'active' member
std:: memcpy(u.a16, &u32, sizeof(u32));

// what is the 'active member' of u now, after the memcpy?
cout << u.a16[0] << ' ' << u.a16[1] << endl; // i.e. is this OK?

Which member of the union, u.whatever or u.a16 , is the 'active member'?

Aucun commentaire:

Enregistrer un commentaire