From http://en.cppreference.com/w/cpp/string/byte/memcpy:
If the objects are not TriviallyCopyable (e.g. scalars, arrays, C-compatible structs), the behavior is undefined.
At my work, we have used std::memcpy
for a long time to bitwise swap objects that are not TriviallyCopyable using:
void swapMemory(Entity* ePtr1, Entity* ePtr2)
{
static const int size = sizeof(Entity);
char swapBuffer[size];
memcpy(swapBuffer, ePtr1, size);
memcpy(ePtr1, ePtr2, size);
memcpy(ePtr2, swapBuffer, size);
}
and never had any issues.
I understand that it is trivial to abuse std::memcpy
with non-TriviallyCopyable objects and cause undefined behavior downstream. However, my question:
Why would the behavior of std::memcpy
itself be undefined when used with non-TriviallyCopyable objects? Why does the standard deem it necessary to specify that?
UPDATE
The contents of http://en.cppreference.com/w/cpp/string/byte/memcpy have been modified in response to this post and the answers to the post. The current description says:
If the objects are not TriviallyCopyable (e.g. scalars, arrays, C-compatible structs), the behavior is undefined unless the program does not depend on the effects of the destructor of the target object (which is not run by
memcpy
) and the lifetime of the target object (which is ended, but not started bymemcpy
) is started by some other means, such as placement-new.
PS
Comment by @Cubbi:
@RSahu if something guarantees UB downstream, it renders the entire program undefined. But I agree that it appears to be possible to skirt around UB in this case and modified cppreference accordingly.