Допустим, у меня есть значение:
int i = 0;
И пустой класс, пригодный для оптимизации на пустых базах:
struct Empty{
// stuff that passes
// static_assert( std::is_empty<Empty>::value );
};
Законно ли это:
Empty& e = *reinterpret_cast<Empty*>(reinterpret_cast<void*>(&i)); //?
// do stuff with e
Согласно этому проект стандарта C ++ онлайн, приведение от одного типа указателя к другому типу указателя и затем обратно условно допустимо:
5.2.10 Переосмыслить приведение
(7) Преобразование значения типа «указатель на T1» в тип «указатель»
в T2 ”(где T1 и T2 — типы объектов и где выравнивание
требования T2 не более строгие, чем требования T1) и обратно к
Исходный тип возвращает исходное значение указателя.
Это означает, что актерский состав сам по себе из int*
в Empty*
действует до тех пор, пока Empty
не имеет более строгих требований к выравниванию, чем int
и позже вы можете откинуть int*
,
Обратите внимание, однако, что это не означает, что вы можете получить доступ / разыменовать Empty*
-объект (так как это не Empty
-объект, на который указывает указатель).
Таким образом, с чистым приведением все в порядке, но разыменование дает UB.
Других решений пока нет …