Если попытки программы для доступ к сохраненному значению объекта через в glvalue, отличный от одного из следующих типов поведения является неопределенными:
- динамического типа объекта,
- вольтамперной квалифицированной версии динамического типа объекта,
- типа похож (как это определенно в 4.4) с динамическим типом объекта,
- типа, который является знаком или без знака типа, соответствующего динамического типа объекта,
- типа, который является подписанным или неподписанный тип, соответствующий стандартной версии динамического типа объекта cv,
- тип агрегата или объединения, который включает один из вышеупомянутых типов среди его элементов или нестатических элементов данных (включая, рекурсивно, элемент или не- -статический элемент данных субагрегата или содержит объединение),
- тип, который является (возможно, cv-qualifie d) тип базового класса динамического типа объекта,
- char или unsigned char type.
ответ
Читатели должны знать, что этот пункт цитируется ОР является религиозным вопросом, как основа спорного поведения компилятора в г ++. Любой ответ на вопрос о точности или полноте этого абзаца (и это не так), как правило, будет опущен на SO.
Вот пример УБ в соответствии с пунктом вы со ссылкой:
struct X { int i; };
auto main() -> int
{
X o{ 0 };
return reinterpret_cast<int&>(o);
}
Учитывая каждую возможность в C++ 11 §3.10/10 в следующем порядке:
Is “ динамический тип объекта ”
o
aint
?
No, динамический типX
.ли
int
возможно “ резюме -qualified версия ” динамического типа X?
No,X
не являетсяint
, cv -qualified или нет.int
“ тип, аналогичный (как определено в 4.4), для динамического типа объекта ”?
Опять же, нет. 4.4 относится к многоуровневому cv -qualification.Ну, это
int
“ тип, который является подписанным или неподписанным типом, соответствующим динамическому типу объекта ”?
Нет, нет никаких подписанных или неподписанных версий типа класса, такого какX
.А как насчет “ типа, который является подписанным или неподписанным типом, соответствующим версии с динамическим типом объекта cv ”?
No.Ну, это, возможно,
int
“ агрегата или объединения типа, который включает в себя один из указанных выше типов между его элементами или нестатическими элементами данных (в том числе, рекурсивно, элемента или нестатический элемента данных в subaggregate или содержащегося союза) ”?
No, не так.Так может быть, это
int
“ типа, который является (возможно, резюме квалифицированного) базового класс типа динамического типа объекта ”?
No, aint
can ’ t быть базовым классом.Наконец, это
int
“char
илиunsigned char
типа ”?
No.
И это исчерпывает все возможности, доказывая, что в соответствии с этого пункта в изоляции, этот код Неопределенное поведение.
Однако этот код гарантированно работает другой частью стандарта (я предполагаю, в основном, для совместимости с C).
Итак, абзац, который вы цитируете, не на 100% хорош даже для полностью независимой от платформы формальной.
Edit: "DYP" спросили в комментариях, как это относится к использованию в xvalue. Значение x - это значение glvalue, поэтому можно просто заменить xvalue для выражения lvalue o
. Примером такого значения x является ссылочное значение rvalue, возвращаемое функцией, например. от std::move
:
#include <utility>
using std::move;
struct X { int i; };
template< class T >
auto ref(T&& r) -> T& { return r; }
auto main() -> int
{
X o{ 0 };
return reinterpret_cast<int&>(ref(move(o)));
}
Все это делает, однако, чтобы маскировать предметы первой необходимости.
Где xvalue/есть xvalue в вашем ответе? – dyp
Кроме того, это не является примером возможного отказа строгого сглаживания. – Ayrosa
Действительно ли это не обращение к хранимому значению объекта 'int' через значение gl типа' int'? Я позволю, чтобы «int &» был получен путем окольного пути с помощью правила указателя-первого-элемента-стандартного макета-класса, но доступ к 'int' через значение int int gl нарушает стриктуры 3.10. – Casey
Я не совсем уверен, что вы ищете. Это что-то вроде 'int i = 42; double j = reinterpret_cast (std :: move (i)); ', где мы создаем значение xvalue через' std :: move (i) ', а затем нарушаем правило строгий псевдоним? –
dyp
Все примеры, которые я видел в нарушениях правила строгого псевдонимов, используют lvalues (разыменование указателя). Мне любопытно увидеть один пример, используя xvalue, если это возможно. AFAICT, я не думаю, что ваш пример характеризует строгий псевдоним. На самом деле он не компилируется. – Ayrosa
Ну, это интересно.Да, я должен был проверить, что он компилируется, но на самом деле * делает * компиляцию на clang ++. Не на g ++ 4.9. [Живой пример] (http://coliru.stacked-crooked.com/a/e1382895e9a81154). (Я бы предположил, что это ошибка g ++.) Проблема с псевдонимом в моем примере заключается в том, что хранимое значение объекта типа 'int' (с именем' i') доступно через значение x типа 'double'. - Edit, ah, ok это проблема C++ 11 vs C++ 14. См. Http://stackoverflow.com/q/26793072 Вот аналогичная проблема с псевдонимом, написанная для C++ 11: http://coliru.stacked-crooked.com/a/d4d04f41104f10bc – dyp