При каких условиях безопасно использовать std :: memcpy для копирования между объектами? - PullRequest
2 голосов
/ 22 января 2020

При каких условиях можно безопасно использовать std::memcpy для копирования с одного объекта на другой?

Например, какие условия должны удовлетворять T, src и dest для следующие для безопасности:

template <typename T>
void copy_bytewise(T& dest, const T& src) {
  std::memcpy(&dest, &src, sizeof(T));
}

Единственное, что мы можем предположить о src и dest, это то, что они не перекрываются 1 . В частности, либо src, либо dest может быть ссылкой на члена или базовый класс.

Меня интересуют ответы, которые относятся к стандарту, но если это отличается от обычной практики (например, де-факто C ++ ABI от Itanium) Также хотелось бы знать.

Обратите внимание, что T, удовлетворяющий концепции TriviallyCopyable (T C), недостаточно, как показывает этот пример . base является T C, но не является memcpy-безопасным (из-за повторного использования заполнения для членов производного класса).

Меня особенно интересует, есть ли любое условие только на T этого достаточно (и не обязательно необходимо), не требуя условий на src и dest (которые, как правило, не могут быть определены статически).


1 В частности, я предполагаю, что если они do пересекаются, их все равно можно безопасно копировать при тех же условиях на T, что и для std::memcpy, но вместо этого используйте std::memmove. Если предположение неверно, это может быть частью ответа.

1 Ответ

4 голосов
/ 22 января 2020

С [basi c .types] / 3:

Для любого тривиально копируемого типа T, если два указателя на T указывают на различимые T объекты obj1 и obj2, где ни obj1, ни obj2 не является подобъектом базового класса, если нижележащие байты ([intro.memory]), составляющие obj1, копируются в obj2, obj2 должен впоследствии иметь то же значение, что и obj1.

Вкратце:

каким условиям должен удовлетворять T, чтобы следующие условия были безопасными

T должно быть тривиально копируемым; это единственное условие, которое T должно удовлетворять. Другое требование - не ограничение на T, а ограничение на характер объектов, которые могут быть скопированы. Это означает, что это не то, что вы можете определить статически.

...