A trivial class is trivially copyable and has a trivial default constructor (a trivial type is either one of those or a built-in class that works similarly).
Since you can use memcpy
to copy objects of trivial types, and since default-initializing trivial types doesn't change any of the bytes in the representation¹, does the following code (using C++20 concepts) correctly initialize a copy of the passed-in object?
#include <cstdlib>
#include <cstring>
#include <new>
#include <type_traits>
template <typename T>
T* copy_trivial(T orig) requires std::is_trivial_v<T>
{
void* buf = std::aligned_alloc(alignof(T), sizeof(T));
// Note the order of these statements
std::memcpy(buf, &orig, sizeof(T));
return new(buf) T;
}
(Compiler Explorer, with a couple instantiations provided)
It seems like this code would work, because there would be an initialized object with the correct object representation. However, given that nothing happens after initialization, would the object instead have an indeterminate value²?
¹ Not specified in a single location, but the linked procedure for default-initialization calls the constructor, which must be implicitly defined; the implicitly defined constructor default-initializes all the members and bases; and that recursion bottoms out at no initialization is performed for the built-in trivial types.
² The note in [expr.new]p18.1 says that it would, but notes are non-normative and it's plausible that this is only the case for non-placement new
.