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