Безопасно ли копировать байты объекта в массив и обратно? - PullRequest
5 голосов
/ 22 января 2020

Безопасно ли копировать байты объекта в массив unsigned char, а затем обратно, используя memcpy, и оставляет ли объект неизменным?

То есть следующее безопасно для любого t:

template <typename T>
void copy_back_and_forth(T& t) {
  unsigned char buf[sizeof(T)];
  std::memcpy(buf, &t, sizeof(T));
  std::memcpy(&t, buf, sizeof(T));
}

... и оставляет ли оно t без изменений?

1 Ответ

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

Значение t гарантированно не изменится, если T является типом, легко копируемым, а t не является потенциально перекрывающимся подобъектом. Стандартная цитата из последнего черновика:

[basi c .types]

Для любого объекта (кроме потенциально перекрывающегося подобъекта) тривиально копируемого типа T, независимо от того, является он или нет объект содержит допустимое значение типа T, базовые байты ([intro.memory]), составляющие объект, могут быть скопированы в массив char, unsigned char или std :: byte ([cstddef.syn]) . 37 Если содержимое этого массива копируется обратно в объект, объект должен впоследствии сохранить свое первоначальное значение.

37) Используя, например, библиотечные функции ([заголовки ]) std :: memcpy или std :: memmove.

Фактически, стандарт имеет почти идентичный пример:

[Пример:

constexpr std::size_t N = sizeof(T);
char buf[N];
T obj;                          // obj initialized to its original value
std::memcpy(buf, &obj, N);      // between these two calls to std​::​memcpy, obj might be modified
std::memcpy(&obj, buf, N);      // at this point, each subobject of obj of scalar type holds its original value

- конец примера]

...