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.
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.
1 Answer
Reset to default 1There isn’t any one strong reason, just several general concerns:
- symmetry (generally one would expect to be able to reverse such a function)
- virtual pointers (though, like other pointers, these could be disallowed only for constant evaluation)
- compatibility with
std::memcpy
(in the absence of any other official means of accessing and imbuing object representations)
From
does not need to be suitable for a bitwise copy. It only needs to be suitable for a bitwise read. As of now, bitwise read is technically a UB, but that is considered a language defect to be corrected, per the paper P1839R7 – lobelk Commented 13 hours ago