Сообщение bit_cast от 18.06.2016 13:13
Изменено 18.06.2016 13:53 S. Schlongberg
Здравствуйте, T4r4sB, Вы писали:
TB>memmove позволяет битово копировать данные разных типов без УБЭ. Но от огребания от индейца не спасёт, как уже сказали.
Похоже, memcpy самый годный способ. Clang, GCC и MSVC его оптимизируют на mov. Хотя, окончательное решение, что использовать, буду принимать на основе бенчмарков.
В проекте Chromium даже есть функция bit_cast, которая именно так и сделана.
https://chromium.googlesource.com/chromium/src/+/1587f7d/base/macros.h#76
А вот с memmove еще интересней. Согласно пунктам 3.9.2 и 3.9.2 стандарта C++ 14, получается, я могу сделать так:
То есть обход strict aliasing rule заключается в вызове ничего не делающей memmove.
TB>memmove позволяет битово копировать данные разных типов без УБЭ. Но от огребания от индейца не спасёт, как уже сказали.
Похоже, memcpy самый годный способ. 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.2 стандарта C++ 14, получается, я могу сделать так:
template <class Dest, class Source>
inline Dest bit_cast(Source& source) {
static_assert(sizeof(Dest)==sizeof(Source), "size of destination and source objects must be equal");
static_assert(std::is_trivially_copyable<Dest>::value, "destination type must be trivially copyable.");
static_assert(std::is_trivially_copyable<Source>::value, "source type must be trivially copyable");
return *((Dest*)std::memmove(&source, &source, sizeof(Dest)));
}То есть обход strict aliasing rule заключается в вызове ничего не делающей memmove.
Здравствуйте, T4r4sB, Вы писали:
TB>memmove позволяет битово копировать данные разных типов без УБЭ. Но от огребания от индейца не спасёт, как уже сказали.
Похоже, memcpy самый годный способ. Clang, GCC и MSVC его оптимизируют на mov. Хотя, окончательное решение, что использовать, буду принимать на основе бенчмарков.
В проекте Chromium даже есть функция bit_cast, которая именно так и сделана.
https://chromium.googlesource.com/chromium/src/+/1587f7d/base/macros.h#76
А вот с memmove еще интересней. Согласно пунктам 3.9.2 и 3.9.3 стандарта C++ 14, получается, я могу сделать так:
То есть обход strict aliasing rule заключается в вызове ничего не делающей memmove.
TB>memmove позволяет битово копировать данные разных типов без УБЭ. Но от огребания от индейца не спасёт, как уже сказали.
Похоже, memcpy самый годный способ. 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) {
static_assert(sizeof(Dest)==sizeof(Source), "size of destination and source objects must be equal");
static_assert(std::is_trivially_copyable<Dest>::value, "destination type must be trivially copyable.");
static_assert(std::is_trivially_copyable<Source>::value, "source type must be trivially copyable");
return *((Dest*)std::memmove(&source, &source, sizeof(Dest)));
}То есть обход strict aliasing rule заключается в вызове ничего не делающей memmove.