了解关于左值到右值转换的示例 [英] Understanding the example on lvalue-to-rvalue conversion

查看:544
本文介绍了了解关于左值到右值转换的示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我很难理解这段代码(来自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 ,引用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆