My reading of the standard is that
std::memcpy is safe whenever the type is trivially copyable.
From 9 Classes, we can see that
unions are class types and so trivially copyable applies to them.
A union is a class defined with the class-key union; it holds only one data member at a time (9.5).
A trivially copyable class is a class that:
- has no non-trivial copy constructors (12.8),
- has no non-trivial move constructors (12.8),
- has no non-trivial copy assignment operators (13.5.3, 12.8),
- has no non-trivial move assignment operators (13.5.3, 12.8), and
- has a trivial destructor (12.4).
The exact meaning of trivially copyable is given in 3.9 Types:
For any object (other than a base-class subobject) of trivially copyable type
T, whether or not the object holds a valid value of type
T, the underlying bytes (1.7) making up the object can be copied into an array of
unsigned char. If the content of the array of
unsigned charis copied back into the object, the object shall subsequently hold its original value.
For any trivially copyable type
T, if two pointers to
Tpoint to distinct
obj2, where neither
obj2is a base-class subobject, if the underlying bytes (1.7) making up
obj1are copied into
obj2shall subsequently hold the same value as
The standard also gives an explicit example of both.
So, if you were copying the entire union, the answer would be unequivocally yes, the active member will be “copied” along with the data. (This is relevant because it indicates that
std::memcpy must be regarded as a valid means of changing the active element of a union, since using it is explicitly allowed for whole union copying.)
Now, you are instead copying into a member of the union. The standard doesn’t appear to require any particular method of assigning to a union member (and hence making it active). All it does is specify (9.5) that
[ Note: In general, one must use explicit destructor class and placement new operators to change the active member of a union. — end note]
which it says, of course, because C++11 allows objects of non-trivial type in unions. Note the “in general” on the front, which quite clearly indicates that other methods of changing the active member are permissible in specific cases; we already know this to be the case because assignment is clearly permitted. Certainly there is no prohibition on using
std::memcpy, where its use would otherwise be valid.
So my answer is yes, this is safe, and yes, it changes the active member.