简体   繁体   中英

Can is_trivially_copy_assignable and is_trivially_copy_constructible be exploited for optimization purposes?

It seems that values aren't safe to copy with memcpy unless the type is trivially copyable, ie satisfies the std::is_trivially_copyable type trait. I wonder what the purpose of the type traits std::is_trivially_copy_assignable , std::is_trivially_copy_constructible , std::is_trivially_move_assignable and std::is_trivially_move_constructible is if you can't exploit them for initialization or assignment with memcpy . Do they permit other optimizations?

I also wonder why the standard requires a trivial destructor for values to be copyable with memcpy . (A trivial destructor does simplify physically moving a value in memory, but it doesn't seem to be fundamentally necessary for just duplicating a value with memcpy ).

I wonder what the purpose of the type traits std::is_trivially_copy_assignable , std::is_trivially_copy_constructible , std::is_trivially_move_assignable and std::is_trivially_move_constructible if you can't exploit them for initialization or assignment with memcpy

They tell you properties of the type, isn't that enough reason to exist?

You might have a type which has a trivial copy constructor but a non-trivial move constructor, so it would not qualify as a trivially copyable type, but is trivially-copy-constructible.

When using such a type you could use SFINAE or other static polymorphism to enable/disable certain operations unless they're guaranteed to be trivial. For example imagine a class template TrivialPair<A,B> which could declare its move constructor as deleted if A and B are not trivially move constructible, and similarly for the other operations. That would mean that TrivialPair only supports operations which A and B both support and which don't call any non-trivial functions.

I also wonder why the standard requires a trivial destructor for values to be copyable with memcpy

"Trivially copyable" can be thought of as saying the type is just a bunch of bytes, ie just data that can be copied to another place in memory safely and without altering the value. If the type has a non-trivial destructor then it's not just a bunch of bytes, it has some additional behaviour which the compiler doesn't comprehend, and which might make using memcpy unsafe.

Sure. One could write a vector class template that exploits this and invokes std::memcpy in its copy constructor in case it's safe to do so. I believe at least one implementations of std::copy employs a similar optimization for the case when the iterators are of type T* and T is trivially copyable.

My guess is that this is just like any other nitpick in the standard. Somewhere out there Joe and Jane will be talking about how a char is 8 bits, and Bob will come in yelling about how the standard says it's actually "8 or MORE bits!" The next day they'll be doing doing some type punning hackery by copying a float into a uint32_t and doing some bit twiddling based on IEEE-754, and Bob will come in again yelling about how IEEE-754 isn't strictly required, and he'll insist that the bit twiddling they're doing might cause some theoretical machine out there to implode the universe.

Damn it Bob!

In practice it's plainly obvious that std::is_trivially_copy_assignable means that the expression "A = B" will just evaluate to a memcpy(), so go ahead and take advantage. Sure there might be some obscure implementation out there which goes out of it's way to give you the finger when you memcpy() a type that isn't strictly std::is_trivially_copyable, and I'm sure Bob is probably the author of said implementation, but do you really care?

This is just my guess, mind you. I have some moderate experience in this area, but I'm by no means a world class expert in C++ minutiae. If I'm wrong on this (in practice, not just in theory) then please feel free to let me know. I'd also love to see a machine with CHAR_BIT > 8 (which I would actually care about), or a machine with non IEEE-754 floats (again, which I would actually care about).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM