Пример кода:
struct S { int x; };
int func()
{
S s{2};
return (int &)s; // Equivalent to *reinterpret_cast<int *>(&s)
}
Я считаю, что это распространено и считается приемлемым. Стандарт гарантирует, что в структуре нет начального заполнения. Однако этот случай не указан в правиле строгого алиасинга (C ++ 17 [basic.lval] / 11):
Если программа пытается получить доступ к сохраненному значению объекта через glvalue другого, чем один из следующих типов, поведение не определено:
- (11.1) динамический тип объекта,
- (11.2) cv-квалифицированная версия динамического типа объекта,
- (11.3) тип, аналогичный (как определено в 7.5) динамическому типу объекта,
- (11.4) тип, который является типом со знаком или без знака, соответствующим динамическому типу объекта,
- (11.5) тип, который является типом со знаком или без знака, соответствующим cv-квалифицированной версии динамического типа объекта,
- (11.6) агрегатный или объединенный тип, который включает в себя один из вышеупомянутых типов среди своих элементов или нестатических элементов данных (включая, рекурсивно, элемент или нестатический элемент данных субагрегата или содержащего объединения),
- (11.7) тип, который является (возможно, cv-квалифицированным) типом базового класса динамического типа объекта,
- (11.8) тип char, unsigned char или std :: byte.
Кажется очевидным, что объект s
имеет доступ к сохраненному значению.
Типы, перечисленные в пунктах маркированного списка, являются типом glvalue, осуществляющим доступ , а не типом объекта, к которому осуществляется доступ. В этом коде тип glvalue равен int
, который не является агрегатным или объединенным типом, исключая 11.6.
У меня вопрос: правильный ли этот код, и если да, то под каким из вышеперечисленных пунктов он разрешен?