了解关于左值到右值转换的示例 [英] Understanding the example on lvalue-to-rvalue conversion
问题描述
我很难理解这段代码(来自C ++ 14草案标准 [conv.lval] 的示例)如何调用未定义的行为 g(false)
。为什么 constexpr
使程序有效?
此外,不访问 yn
?在 g()
的两个调用中,我们返回了 n
数据成员为什么最后一行说' t访问它?
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); //未定义的行为,由于访问x.n外面的
//生命周期
int n = g(true); // OK,does not access yn
yn
不是odr使用,因此不需要访问 yn
odr使用的规则覆盖 3.2
并说:
变量x的名称显示为潜在评估除非将
lvalue-to-rvalue转换(4.1)应用于x 产生一个常量表达式(5.19),而不调用任何非平凡
函数,并且如果x是对象,则ex是表达式e的潜在结果集合的元素,其中
左值到右值转换(4.1)应用于e ,或者e是丢弃值表达式
注意,Ben Voigt做了一些有用的评论,这一点。因此,这里的工作假设是 x :
y
和 e 将是( e定义的不同表达式在第2 ):
$ c> y
产生常数表达式,并将左值到右值转换应用于
由于 f
产生一个lambda,捕获<$ c $一旦调用 f $ c $>,引用
因为 x
的c> f x
是 f
中的自动变量。由于 y
是一个常量表达式,它的行为好像 yn
您的示例包含在 N3939 section 4.1
[conv.lval] 说:
当对表达式e应用左值到右值转换时,以及
并包括考试所属的以下项目符号:
e导致对e的潜在结果集合中的成员ex的评估,并且
ex表示由ex(3.2),不是odr使用的变量x >
然后:
在所引用的对象中未被访问
由于缺陷报告1773 。
I have a hard time understanding how this code (an example from the C++14 draft standard [conv.lval]) invokes undefined behavior for g(false)
. Why does constexpr
make the program valid?
Also, what does it mean by "does not access y.n
"? In both calls to g()
we are returning the n
data member so why does the last line say it doesn't access it?
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
This is because y.n
is not odr-used and therefore does not require an access to y.n
the rules for odr-use are covered in 3.2
and says:
A variable x whose name appears as a potentially-evaluated expression ex is odr-used unless applying the lvalue-to-rvalue conversion (4.1) to x yields a constant expression (5.19) that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (4.1) is applied to e, or e is a discarded-value expression
Note, Ben Voigt made some helpful comments that clarified this one a bit. So the working assumption here is that x would be:
y
and e would be(the different expression that e is defined for is covered in paragraph 2 of section 3.2):
(b ? y : x).n
y
yields a constant expression and the lvalue-to-rvalue conversion is applied to the expression e.
Since f
yields a lambda which captures f
's local variables by reference x
is no longer valid once the call to f
is done since x
is an automatic variable inside f
. Since y
is a constant expression it acts as if y.n
was not accessed and therefore we don't have the same lifetime issue.
Your example is included in N3939 section 4.1
[conv.lval] and right before that example it says:
When an lvalue-to-rvalue conversion is applied to an expression e, and either
and includes the following bullet which the examle belongs to:
the evaluation of e results in the evaluation of a member ex of the set of potential results of e, and ex names a variable x that is not odr-used by ex (3.2),
then:
the value contained in the referenced object is not accessed
This was applied to the C++14 draft standard due to defect report 1773 .
这篇关于了解关于左值到右值转换的示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!