Возможный дубликат:
Псевдоним `T *` с `char *` разрешен. Это также разрешено наоборот?
Я использую std::array
из char
s для хранения значения неизвестного примитивного типа длиной не более 10 байт, например:
std::array<char, 10> val;
*reinterpret_cast<double*>(val.data()) = 6.3;
//blah blah blah...
double stuff = *reinterpret_cast<double*>(val.data());
Я прочитал этот отлив char *
не является неопределенным, потому что компилятор предполагает char *
может иметь псевдоним значения любого типа. Это все еще работает, когда значение помещается в (что я предполагаю, что) массив char
внутри объекта?
Примечание: я знаю, что я мог бы использовать объединение здесь, но это привело бы к большому количеству стандартного кода для того, что я делаю, и я хотел бы избежать этого в случае необходимости, поэтому возникает вопрос.
Да, std::array< char, 10 >
не удовлетворяет требованиям выравнивания double
чтобы reinterpret_cast
провоцирует UB.
Пытаться std::aligned_storage
вместо.
Неважно, в чем содержится массив.
Стандарт даже не учитывает, что что-то окружает (это так просто), но поддерживает преобразование в / из char
последовательности.
Чтобы сделать это напрямую через reinterpret_cast
и назначение, вы должны правильно выровнять буфер.
Альтернативой является использование memcpy
, который не заботится о выравнивании.
Что касается смежного вопроса, то, как правило, не рекомендуется переходить на двоичный уровень. Например, простое изменение версии компилятора может сделать файл двоично-сериализованных данных недоступным. В любом случае, основным драйвером для этого являются необработанные соображения производительности.