2014-12-15 6 views
0

3.10/10Пример о том, как получить доступ к значению объекта через xvalue, чтобы спровоцировать UB, как описано в 3.10/10 в C++ 11 Стандартный

Если попытки программы для доступ к сохраненному значению объекта через в glvalue, отличный от одного из следующих типов поведения является неопределенными:

  • динамического типа объекта,
  • вольтамперной квалифицированной версии динамического типа объекта,
  • типа похож (как это определенно в 4.4) с динамическим типом объекта,
  • типа, который является знаком или без знака типа, соответствующего динамического типа объекта,
  • типа, который является подписанным или неподписанный тип, соответствующий стандартной версии динамического типа объекта cv,
  • тип агрегата или объединения, который включает один из вышеупомянутых типов среди его элементов или нестатических элементов данных (включая, рекурсивно, элемент или не- -статический элемент данных субагрегата или содержит объединение),
  • тип, который является (возможно, cv-qualifie d) тип базового класса динамического типа объекта,
  • char или unsigned char type.
+0

Я не совсем уверен, что вы ищете. Это что-то вроде 'int i = 42; double j = reinterpret_cast (std :: move (i)); ', где мы создаем значение xvalue через' std :: move (i) ', а затем нарушаем правило строгий псевдоним? – dyp

+0

Все примеры, которые я видел в нарушениях правила строгого псевдонимов, используют lvalues ​​(разыменование указателя). Мне любопытно увидеть один пример, используя xvalue, если это возможно. AFAICT, я не думаю, что ваш пример характеризует строгий псевдоним. На самом деле он не компилируется. – Ayrosa

+0

Ну, это интересно.Да, я должен был проверить, что он компилируется, но на самом деле * делает * компиляцию на 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

ответ

-5

Читатели должны знать, что этот пункт цитируется ОР является религиозным вопросом, как основа спорного поведения компилятора в г ++. Любой ответ на вопрос о точности или полноте этого абзаца (и это не так), как правило, будет опущен на SO.

Вот пример УБ в соответствии с пунктом вы со ссылкой:

struct X { int i; }; 

auto main() -> int 
{ 
    X o{ 0 }; 
    return reinterpret_cast<int&>(o); 
} 

Учитывая каждую возможность в C++ 11 §3.10/10 в следующем порядке:

  • Is “ динамический тип объекта ” o a int?
    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, a int can ’ t быть базовым классом.

  • Наконец, это intchar или 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))); 
} 

Все это делает, однако, чтобы маскировать предметы первой необходимости.

+1

Где xvalue/есть xvalue в вашем ответе? – dyp

+1

Кроме того, это не является примером возможного отказа строгого сглаживания. – Ayrosa

+0

Действительно ли это не обращение к хранимому значению объекта 'int' через значение gl типа' int'? Я позволю, чтобы «int &» был получен путем окольного пути с помощью правила указателя-первого-элемента-стандартного макета-класса, но доступ к 'int' через значение int int gl нарушает стриктуры 3.10. – Casey