Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a reference member out of scope

This question concerns the function stack and reference members (which I read are considered bad practice in general). My test code:

#include <iostream>
using namespace std;

struct Person 
{
    Person(const int& s) : score(s) {}
    const int& score;
};

int main()
{
    Person p(123);
    cout << "P's score  is: " << p.score << endl;
    return 0;
}

We create an integer object in Person's constructor. A template object is created because of converting int into &int (and that's why we need const). Then we set score point to the constructor's argument. Finally, we exit the constructor and the argument is destroyed.

Output:

P's score is: 123

How come we are still getting the value 123 if the argument was destroyed? It would make sense to me if we copied the argument to the member. My logic tells me the member would point to an empty location which is obviously incorrect. Maybe the argument is not really destroyed but instead it just goes out of scope?

This question arose when I read this question: Does a const reference prolong the life of a temporary?

I find Squirrelsama's answer clear and I thought I understood it until I tried this code.

Update 2/12/2018: More information about this: What happens when C++ reference leaves it's scope?

Update 2/18/2018: This question was made in not clear understanding of how references, pointers and dynamic memory work in C++. Anyone struggling with this, I recommend reading about those.

like image 409
Trollblender Avatar asked Oct 15 '25 18:10

Trollblender


1 Answers

How come we are still getting the value 123 if the argument was destroyed?

Because nothing guarantees you won't. In C++, accessing an object whose lifetime has ended (and your temporary is dead when you access it) results in undefined behavior. Undefined behavior doesn't mean "crash", or "get empty result". It means the language specification doesn't prescribe an outcome. You can't reason about the results of the program from a pure C++ perspective.

Now what may happen, is that your C++ implementation reserves storage for that temporary. And even though it may reuse that location after p is initialized, it doesn't mean it has to. So you end up reading the "proper value" by sheer luck.

like image 93
StoryTeller - Unslander Monica Avatar answered Oct 18 '25 08:10

StoryTeller - Unslander Monica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!