Это использование std :: array неопределенное поведение?

Возможный дубликат:
Псевдоним `T *` с `char *` разрешен. Это также разрешено наоборот?

Я использую std::array из chars для хранения значения неизвестного примитивного типа длиной не более 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внутри объекта?

Примечание: я знаю, что я мог бы использовать объединение здесь, но это привело бы к большому количеству стандартного кода для того, что я делаю, и я хотел бы избежать этого в случае необходимости, поэтому возникает вопрос.

8

Решение

Да, std::array< char, 10 > не удовлетворяет требованиям выравнивания double чтобы reinterpret_cast провоцирует UB.

Пытаться std::aligned_storage вместо.

13

Другие решения

Неважно, в чем содержится массив.

Стандарт даже не учитывает, что что-то окружает (это так просто), но поддерживает преобразование в / из char последовательности.

Чтобы сделать это напрямую через reinterpret_cast и назначение, вы должны правильно выровнять буфер.

Альтернативой является использование memcpy, который не заботится о выравнивании.

Что касается смежного вопроса, то, как правило, не рекомендуется переходить на двоичный уровень. Например, простое изменение версии компилятора может сделать файл двоично-сериализованных данных недоступным. В любом случае, основным драйвером для этого являются необработанные соображения производительности.

0

По вопросам рекламы [email protected]