Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
548 views
in Technique[技术] by (71.8m points)

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

struct A {
    A(int) : i(new int(783)) {
        std::cout << "a ctor" << std::endl;
    }

    A(const A& other) : i(new int(*(other.i))) {
        std::cout << "a copy ctor" << std::endl;
    }

    ~A() {
        std::cout << "a dtor" << std::endl;
        delete i;
    }

    void get() {
        std::cout << *i << std::endl;
    }

private:
    int* i;
};

const A& foo() {
    return A(32);
}

const A& foo_2() {
    return 6;
}

int main()
{
    A a = foo();
    a.get();
}

I know, returning references to local values is bad. But, on the other hand, const reference should extend a temporary object lifetime.

This code produce an UB output. So no life extention.

Why? I mean can someone explain whats happening step by step?

Where is fault in my reasoning chain?

foo():

  1. A(32) - ctor

  2. return A(32) - a const reference to local object is created and is returned

  3. A a = foo(); - a is initialized by foo() returned value, returned value goes out of scope(out of expression) and is destroyed, but a is already initialized;

(But actually destructor is called before copy constructor)

foo_2():

  1. return 6 - temp object of type A is created implicitly,a const reference to this object is created(extending its life) and is returned

  2. A a = foo(); - a is initialized by foo() returned value, returned value goes out of scope(out of expression) and is destroyed, but a is already initialized;

(But actually destructor is called before copy constructor)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...