Understanding the example on lvalue-to-rvalue conversion

拜拜、爱过 提交于 2019-11-26 08:38:23

问题


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

回答1:


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 .



来源:https://stackoverflow.com/questions/28506342/understanding-the-example-on-lvalue-to-rvalue-conversion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!