https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68350
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |missed-optimization Last reconfirmed|2015-11-14 00:00:00 |2019-2-5 --- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> --- To summarise: The original report is wrong, we cannot use trivially-copyable there. The point of the condition is to decide whether to use std::copy, because for trivially-copyable types that is optimized to memmove. But unlike std::uninitialized_copy, std::copy calls no constructors, so the type must be trivially default constructible, and if an exception is thrown, it calls no destructors, so the type must be trivially destructible as well. So we can only use the memmove optimization for types which are trivially-copyable (which implies trivially destructible) and trivially-default-constructible. That's a trivial type, so __is_trivial is the right check. The reason this bug is still open is that the other part of the condition is overly-restrictive: the is_assignable check means that we don't optimize to memmove for this case: #include <memory> struct Y { Y() = default; Y(const Y&) = default; Y& operator=(const Y&) = delete; }; static_assert(std::is_trivially_copyable<Y>::value, ""); int main() { alignas(Y) unsigned char buf[sizeof(Y)]; Y y; std::uninitialized_copy(&y, &y+1, (Y*)buf); } This could be optimized to memmove. However, because std::copy would be ill-formed (because std::copy does an assignment), we cannot use it, and do an explicit copy construction using placement new. This is a missed-optimization.