1

Is it always safe to std::memmove between the same object instances (including subobjects).

That is, is the following safe for any T and any t, and will it leave t unchanged:

template <typename T>
void maybe_copy(T& t) {
  std::memmove(&t, &t, sizeof(T));
}

As a corollary question, is the following always safe:

template <typename T>
void redundant_copy(T& s, const T& d) {
  if (std::addressof(s) == std::addressof(d)) {
    std::memmove(&d, &s, sizeof(T));
  }
}
BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
  • https://en.cppreference.com/w/cpp/string/byte/memmove mentions the cases where the function may cause undefined behavior. Does that not answer your question? – R Sahu Jan 22 '20 at 04:51
  • @RSahu - no, it doesn't, because it applies to an arbitrary copy operation, not to the very restricted case where the object is the same object. In particular, there are various examples in the standard where when bytes are copied from an object into a char buffer, and then back again, some special condition applies, so this case is often distinct. – BeeOnRope Jan 22 '20 at 05:01

1 Answers1

0

No, it is not always safe.

From https://en.cppreference.com/w/cpp/string/byte/memmove

If the objects are potentially-overlapping or not TriviallyCopyable, the behavior of memmove is not specified and may be undefined.

What is potentially-overlapping?
From https://en.cppreference.com/w/cpp/language/object#Subobjects

A subobject is potentially overlapping if it is either

. a base class subobject, or
. a non-static data member declared with the [[no_unique_address]] attribute.

I am assuming I don't need to post the definition of TriviallyCopyable in this answer.

R Sahu
  • 204,454
  • 14
  • 159
  • 270