Implicitly treating returned lvalue as rvalue

后端 未结 2 1403
天涯浪人
天涯浪人 2020-12-16 12:45

12.8 Copying and moving class objects [class.copy] §31 and §32 say:

in a return statement in a function with a class return type, when the expres

相关标签:
2条回答
  • 2020-12-16 13:05

    Parenthesized expressions are equivalent to their unparenthesized expressions unless otherwise noted (as done in the ADL rules, for example, or by decltype for another example). It can sometimes be tricky when and when not something is equivalent in this manner (for example, the ADL rules don't explicitly mention "unparenthesized", but they use an explicit grammar non-terminal and examples that make it clear that parens are not taken as being equivalent).

    For the other questions: Yes, GCC does several optimizations on the AST directly that makes it accept various invalid programs, like the following

    int a = 42;
    int *p = 0 * a;
    
    0 讨论(0)
  • 2020-12-16 13:08

    Regarding parenthesized expressions [√]

    You are wrong when talking about parenthesized expressions and that it shouldn't be able to trigger a move when being returned and containing only the name of a moveable object.

    5.1.1/1      General      [expr.prim.general]

    A parenthesized expression is a primary expression whose type and value are identical to those of the enclosed expression. The presence of parentheses does not affect whether the expression is an lvalue. The parenthesized expression can be used in exactly the same contexts as those where the enclosed expression can be used, and with the same meaning, except as otherwise indicated.


    Regarding the constexpr conditional operator [╳]

    The way I interpret the standard in regards to constant-expressions and he coditional operator is that the use of return true ? result : result is well-behaved since it is a constant expression and therefore equivalent to return result;

    I have now gone through the standard more carefully and nowhere does it say that a constant conditional-expression is the same as if only the "returned" expression would have been written.

    true ? <expr1> : <expr2>; // this is not the same as just writing <expr1>;
    

    Regarding return *&result; [╳]

    In C99 it is explicitly stated that *&result is the exact equivalent of having written result instead, this is not the case in the C++ specification.

    Though we can all agree on that using *&result will indeed yield the same lvalue as result, but according to the standard *&result (of course) isn't an expression where "the expression is the name of a non-volatile automatic object".

    Sure, the expression contains an appropriate name, but it's not just only that.


    To sum things up...

    return result; // #1, OK
    

    return (result);                  // as described earlier, OK
    return true ? result : result;    // as described earlier, ill-formed
    return rand () ? result : result; // as described earlier, ill-formed
    return *&result;                  // as described earlier, ill-formed
    
    0 讨论(0)
提交回复
热议问题