I have found the intricacies of trivial types in C++ non-trivial to understand and hope someone can enlighten me on the following.
Given type T
, storage for T
allocated using ::operator new(std::size_t)
or ::operator new[](std::size_t)
or std::aligned_storage
, and a void * p
pointing to a location in that storage suitably aligned for T
so that it may be constructed at p
:
- If
std::is_trivially_default_constructible<T>::value
holds, is the code invoking undefined behavior when code skips initialization ofT
atp
(i.e. by usingT * tPtr = new (p) T();
) before otherwise accessing*p
asT
? Can one just useT * tPtr = static_cast<T *>(p);
instead without fear of undefined behavior in this case? - If
std::is_trivially_destructible<T>::value
holds, does skipping destruction ofT
at*p
(i.e by callingtPtr->~T();
) cause undefined behavior? - For any type
U
for whichstd::is_trivially_assignable<T, U>::value
holds, isstd::memcpy(&t, &u, sizeof(U));
equivalent tot = std::forward<U>(u);
(for anyt
of typeT
andu
of typeU
) or will it cause undefined behavior?