Понимание примера преобразования lvalue в rvalue

Мне трудно понять, как этот код (пример из проекта стандарта C ++ 14 [Conv.lval]) вызывает неопределенное поведение для g(false), Почему constexpr сделать программу действительной?

Кроме того, что означает «не доступ y.n«? В обоих звонках g() мы возвращаем n элемент данных, так почему последняя строка говорит, что не имеет к нему доступа?

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 due to access of x.n outside its
// lifetime
int n = g(true);  // OK, does not access y.n

4

Решение

Это потому что y.n не используется odr и поэтому не требует доступа к y.n правила использования odr описаны в 3.2 и говорит:

Переменная x, имя которой появляется в качестве потенциально вычисляемого выражения ex используется odr, если применяя
преобразование lvalue в rvalue (4.1) в x дает постоянное выражение (5.19), которая не вызывает никакой нетривиальной
функции и, если x является объектом, ex является элементом множества потенциальных результатов выражения e, где
либо преобразование lvalue в rvalue (4.1) применяется к e, или e является выражением отброшенного значения

Обратите внимание, что Бен Фойгт сделал несколько полезных комментариев, которые немного прояснили этот вопрос. Так что рабочее предположение здесь таково, что Икс было бы:

y

а также е было бы(другое выражение, для которого определено e, рассматривается в пункте 2 раздела 3.2.):

(b ? y : x).n

y дает константное выражение и преобразование lvalue-в-значение применяется к выражению е.

поскольку f дает лямбду, которая захватывает fлокальные переменные по ссылке x больше не действителен после звонка f сделано с x это автоматическая переменная внутри f, поскольку y это постоянное выражение это действует так, как будто y.n не был доступен, и поэтому у нас нет той же проблемы жизни.

Ваш пример включен в N3939 раздел 4.1 [Conv.lval] и прямо перед этим примером написано:

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

и включает в себя следующую маркировку, к которой относится исследование:

оценка результатов e в оценке члена ex из набора потенциальных результатов e, и
ex называет переменную x, которая не используется odr бывший (3.2),

затем:

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

Это было применено к проекту стандарта C ++ 14 из-за Дефект 1773 .

7

Другие решения


По вопросам рекламы [email protected]