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>::valueholds, is the code invoking undefined behavior when code skips initialization ofTatp(i.e. by usingT * tPtr = new (p) T();) before otherwise accessing*pasT? Can one just useT * tPtr = static_cast<T *>(p);instead without fear of undefined behavior in this case? - If
std::is_trivially_destructible<T>::valueholds, does skipping destruction ofTat*p(i.e by callingtPtr->~T();) cause undefined behavior? - For any type
Ufor whichstd::is_trivially_assignable<T, U>::valueholds, isstd::memcpy(&t, &u, sizeof(U));equivalent tot = std::forward<U>(u);(for anytof typeTanduof typeU) or will it cause undefined behavior?