问题描述
我很难理解这段代码(来自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
并说:
注意,Ben Voigt做了一些有用的评论,这一点。因此,这里的工作假设是 x :
y
和 e 将是( e定义的不同表达式在第2 ):
$ c> y
产生常数表达式,并将左值到右值转换应用于
由于 f
产生一个lambda,捕获<$ c $一旦调用 f $ c $>,引用
因为 x
的c> f x
是 f
中的自动变量。由于 y
是一个常量表达式,它的行为好像 yn
您的示例包含在 section 4.1
[conv.lval] 说:
并包括考试所属的以下项目符号:
然后:
由于。
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:
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:
and includes the following bullet which the examle belongs to:
then:
This was applied to the C++14 draft standard due to defect report 1773 .
这篇关于了解关于左值到右值转换的示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!