bit_cast
От: Eeel Россия  
Дата: 18.06.16 13:13
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>memmove позволяет битово копировать данные разных типов без УБЭ. Но от огребания от индейца не спасёт, как уже сказали.


Похоже, memcpy/memmove самый годный способ. Clang, GCC и MSVC его оптимизируют на mov. Хотя, окончательное решение, что использовать, буду принимать на основе бенчмарков.

В проекте Chromium даже есть функция bit_cast, которая именно так и сделана.

https://chromium.googlesource.com/chromium/src/+/1587f7d/base/macros.h#76

template <class Dest, class Source>
inline Dest bit_cast(const Source& source) {
  COMPILE_ASSERT(sizeof(Dest) == sizeof(Source), VerifySizesAreEqual);
  Dest dest;
  memcpy(&dest, &source, sizeof(dest));
  return dest;
}


А вот с memmove еще интересней. Согласно пунктам 3.9.2 и 3.9.3 стандарта C++ 14, получается, я могу сделать так:

template <class Dest, class Source>
inline Dest& bit_cast(Source& source) {
    // Проверки
    
    return *((Dest*)std::memmove(&source, &source, sizeof(Dest)));
}


То есть обход strict aliasing rule заключается в вызове ничего не делающей memmove.

Update: Хотя нет, не получается. Там написано:
For any trivially copyable type T, if two pointers to T point to distinct T objects obj1 and obj2

А у меня объекты-то не различные.
Отредактировано 27.06.2016 18:10 S. Schlongberg . Предыдущая версия . Еще …
Отредактировано 21.06.2016 9:52 S. Schlongberg . Предыдущая версия .
Отредактировано 18.06.2016 14:47 S. Schlongberg . Предыдущая версия .
Отредактировано 18.06.2016 14:43 S. Schlongberg . Предыдущая версия .
Отредактировано 18.06.2016 13:55 S. Schlongberg . Предыдущая версия .
Отредактировано 18.06.2016 13:54 S. Schlongberg . Предыдущая версия .
Отредактировано 18.06.2016 13:53 S. Schlongberg . Предыдущая версия .
Отредактировано 18.06.2016 13:53 S. Schlongberg . Предыдущая версия .
Отредактировано 18.06.2016 13:27 S. Schlongberg . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.