lobelk
lobelk

Reputation: 502

Why does bit cast require both types to be trivially-copyable?

Why does C++ std::bit_cast require both To and From to be trivially-copyable? For example:

From from{};
To to;
static_assert(sizeof to == sizeof from);
std::memcpy(&to, &from, sizeof to);

Here, to will be constructed from from without invoking a copy-constructor, so To obviously has to be trivially-copyable. On the other hand, as per definition, &from is taken as const void*, so none of its constructors would have to be called anyways. Therefore, as far as I can see, From does not really need to be trivially-copyable. And indeed, std::memcpy does not require anything to be trivially-copyable, but std::bit_cast does.

Why does the standard then impose this additional requirement and can it be safely avoided?

Note: this thread discusses why using std::memcpy on non-trivially-copyable types is undefined behavior, but only for the cases where To and From are the same type, and thus, requiring To to be trivially-copyable requires From to be trivially-copyable as well.

Upvotes: 10

Views: 303

Answers (1)

Davis Herring
Davis Herring

Reputation: 40023

There isn’t any one strong reason, just several general concerns:

  1. symmetry (generally one would expect to be able to reverse such a function)
  2. virtual pointers (though, like other pointers, these could be disallowed only for constant evaluation)
  3. compatibility with std::memcpy (in the absence of any other official means of accessing and imbuing object representations)

Upvotes: 5

Related Questions