Проблема с примером после [conv.lval#2.2]

Пример:

struct S { int n; };
auto f() {
S x { 1 };
constexpr S y { 2 };
return [&](bool b) { return (b ? y : x).n; };
}
auto g = f();
int m = g(false);   // undefined behavior: access of x.n outside its lifetime
int n = g(true);    // OK, does not access y.n

Соответствующее правило:

Когда преобразование lvalue-to-rvalue применяется к выражению E, и либо

  1. E потенциально не оценивается, или
  2. оценка E приводит к оценке члена Ex набора потенциальных результатов E, а Ex называет переменную x, которая не используется Ex ([basic.def.odr])

значение, содержащееся в указанном объекте, недоступно.

Я сомневаюсь в выражении y.n, которое отмечено как неиспользуемое из n.

По правилу:

Множество потенциальных результатов выражения E определяется следующим образом:

  • Если E является id-выражением ([expr.prim.id]), набор содержит только E.
  • [...]
  • Если E является выражением доступа к члену класса ([expr.ref]) формы E1 . шаблон opt E2, именующий нестатический член данных, набор содержит потенциальные результаты E1.

Согласно пуле 3, потенциальным результатом выражения y.n является само y, а n действительно является членом y, который является потенциальным результатом y.n. Однако я не согласен с тем, что n не используется.

Согласно этому правилу:
basic.def.odr#4.2

Переменная x, имя которой появляется как потенциально вычисляемое выражение E, используется E odr, если только

  • x — это переменная нессылочного типа, которая может использоваться в константных выражениях и не имеет изменяемых подобъектов, а E — элемент множества потенциальных результатов выражения неклассового типа с неизменяемой квалификацией, к которому относится lvalue- Применяется преобразование в значение ([conv.lval]).

Преобразование lvalue-to-rvalue применяется к выражению y.n, потенциальные результаты которого содержат только объектное выражение y, а не n. Следовательно, согласно [basic.def.odr#4.2], переменная с именем n используется odr выражением n. Итак, g(true) должно быть неопределенным поведением. Как интерпретировать этот пример? Это неправильный пример?

n не содержится в наборе потенциальных результатов (b ? y : x).n и, следовательно, использование odr просто не может применяться к нему.
Language Lawyer 14.12.2020 06:56

@LanguageLawyer Да, я знаю это. что я неправильно понимаю, так это то, что оценка E приводит к оценке элемента Ex набора потенциальных результатов E. Я думал, что элемент данных потенциального результата (y или x) E.

xmh0511 14.12.2020 08:12

И S::n в конце концов не переменная.

Language Lawyer 14.12.2020 09:17

@LanguageLawyer, вы имеете в виду, поскольку S::n не является объектом, значит, это не переменная для basiC# 6, верно?

xmh0511 14.12.2020 09:52
s.n — это объект, но n еще не переменная
Language Lawyer 14.12.2020 11:31

@LanguageLawyer, почему n все еще не является переменной? Я этого не понимаю. вы сказали, что s.n — это объект, вы имеете в виду, что s — это объект типа S? Пожалуйста, интерпретируйте такие два вопроса.

xmh0511 14.12.2020 17:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
87
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема с вашими рассуждениями заключается в том, что [conv.lval]/3.2 не требует, чтобы n не использовался. Рассматриваемое выражение E = (b ? y : x).n. Набор возможных результатов равен {x, y}. Оценка E, когда b = true, в конечном итоге приведет к оценке y. Следовательно, мы можем установить Ex = y, и теперь мы обнаруживаем, что «оценка E приводит к оценке члена Ex множества потенциальных результатов E» является верным утверждением. Предложение теперь требует только, чтобы Ex = y называл переменную, которая не используется odr в Ex. Позвольте мне повторить это, так как я думаю, что это то, где вы ошиблись: [conv.lval]/3.2 спрашивает, использует ли Ex odr-саму себя (или, действительно, переменную, которую он называет). Нам нужно доказательство того, что выражение y не использует odr переменную y. Доступ участника к n не имеет значения.

Ну а мы продолжаем смотреть на [basic.def.odr]/4

Переменная x, имя которой появляется как потенциально вычисляемое выражение E, используется odr E, если только

  • ...
  • x — это переменная нессылочного типа, которая может использоваться в константных выражениях и не имеет изменяемых подобъектов, а E — это элемент множества потенциальных результатов выражения неклассового типа с неизменяемой квалификацией, к которому относится lvalue- применяется преобразование в значение ([conv.lval]), или
  • ...

Обратите внимание, что E здесь — это не E = (b ? y : x).n, с которого мы начали в [const.lval]/3.2. E — это выражение, которое мы тестируем на использование odr y. Назовем его E'. Затем E' = Ex = y, потому что, опять же, мы проверяем, использует ли выражение y odr переменную y. Первая часть условия выполняется; y — это переменная нессылочного типа, которая может использоваться в константных выражениях и не имеет изменяемых подобъектов. Теперь является ли E' = y элементом набора потенциальных результатов для исходного E (поскольку E является выражением неклассового типа с энергонезависимой квалификацией, к которому применяется преобразование lvalue в rvalue)? Да, мы рассмотрели это, y — один из возможных результатов E. Поэтому Ex не использует запах y. Это завершает предварительное условие для [conv.lval]/3.2: теперь мы знаем, что (b ? y : x).n не обращается к значению y.n при оценке преобразования lvalue в rvalue. Поэтому УБ нет. Опять же, обратите внимание, что n вообще не фигурировало в наших рассуждениях.

множество потенциальных результатов E( (b ? y : x).n ) — это множество потенциальных результатов (b? x: y) согласно basic.def.odr#2.7, которые, в свою очередь, потенциальными результатами являются y и x . Итак, множество потенциальных результатов (b?y:x).n) равно {y,x}, верно? Утверждение «оценка E приводит к оценке члена Ex множества потенциальных результатов E» требует только x или y не является odr-used соответствующим выражением. И, насколько я понимаю, для [basic.def.odr#4.2] переменная с именем y не используется odr y.

xmh0511 14.12.2020 08:18

Другие вопросы по теме