Is using memcpy to construct a trivially copyable union UB? Active member?

Viewed 83

I'm worried about undefined behavior. Can you initialize the value of a trivially copyable union type by using a memcpy? This came up when I considered using Boost Serialization with BOOST_IS_BITWISE_SERIALIZABLE(MyUnionType), which I assume uses something like memcpy.

#include <cstring>

enum class Foo: int {};

union Bar {
    int num;
    Foo foo;
};

int baz(int src) {
    Bar dst;

    // My understanding is that memcpy does initialize dst
    // but doesn't set the active member of the union.
    std::memcpy(&dst, &src, sizeof(Bar));

    // My understanding is that whichever member is read
    // first here becomes the active member of the union.
    if (src > 42) {
        return dst.num;
    } else {
        return (int)dst.foo;
    }
}
1 Answers

I don't see an issue with this case, from definition:

A trivially copyable class is a class (defined with class, struct or union) that:

  • uses the implicitly defined copy and move constructors, copy and move assignments, and destructor.
  • has no virtual members.
  • its base class and non-static data members (if any) are themselves also trivially copyable types.

Member lifetime The lifetime of a union member begins when the member is made active. If another member was active previously, its lifetime ends.

Foo in this case is itself trivially copyable

static_assert(std::is_trivially_copyable_v<Bar>);

So I don't see any reason for UB

Related