What exactly happens when returning const reference to a local object?

后端 未结 2 1475
生来不讨喜
生来不讨喜 2020-12-17 20:40
struct A {
    A(int) : i(new int(783)) {
        std::cout << \"a ctor\" << std::endl;
    }

    A(const A& other) : i(new int(*(other.i))) {
              


        
相关标签:
2条回答
  • 2020-12-17 21:23

    You are misinterpeting "until function exit". If you really want to use a const reference to extend the life of an object beyond foo, use

    A foo() {
        return A(32);
    }
    int main() {
        const A& a = foo();
    }
    

    You must return from foo by value, and then use a const reference to reference the return value, if you wish to extend things in the way you expect.

    As @AndreyT has said, the object is destroyed in the function that has the const &. You want your object to survive beyond foo, and hence you should not have const & (or &) anywhere in foo or in the return type of foo. The first mention of const & should be in main, as that is the function that should keep the object alive.

    You might think this return-by-value code is slow as there appear to be copies of A made in the return, but this is incorrect. In most cases, the compiler can construct A only once, in its final location (i.e. on the stack of the calling function), and then set up the relevant reference.

    0 讨论(0)
  • 2020-12-17 21:40

    Rules of temporary lifetime extension for each specific context are explicitly spelled out in the language specification. And it says that

    12.2 Temporary objects

    5 The second context is when a reference is bound to a temporary. [...] A temporary bound to the returned value in a function return statement (6.6.3) persists until the function exits. [...]

    Your temporary object is destroyed at the moment of function exit. That happens before the initialization of the recipient object begins.

    You seem to assume that your temporary should somehow live longer than that. Apparently you are trying to apply the rule that says that the temporary should survive until the end of the full expression. But that rule does not apply to temporaries created inside functions. Such temporaries' lifetimes are governed by their own, dedicated rules.

    Both your foo and your foo_2 produce undefined behavior, if someone attempts to use the returned reference.

    0 讨论(0)
提交回复
热议问题