Reputation: 874
I don't understand how this code works:
class AAA {
public:
short a, b;
};
AAA &getRef() {
AAA aaa = {2, 6};
return aaa;
} // 'aaa' is destroyed here right?
int main() {
AAA &ref = getRef();
cout << ref.a << ", " << ref.b << endl;
cin.ignore();
return 0;
}
Shouldn't there be an error trying to access ref.a
and ref.b
? When I use pointers, I don't get an error either. I mean,this prints "2, 6" every single time.
EDIT: Is it because the memory is still set to those numbers?
Upvotes: 0
Views: 4702
Reputation: 14695
Replace the short
s with a user-defined type with a complicated destructor (like string
), and you will probably see this crash. Because the memory has been reclaimed, but the old value is still sitting there, you can (sometimes) see the value of built-in types (like int
, short
, etc.) even after destruction.
Upvotes: 2
Reputation: 129524
It "works" because the memory for aaa
hasn't been overwritten when the function returns. If you modify the AAA
class to have a destructor that modifies a
and b
, or if you use some code that writes to the stack, it will almost certainly overwrite the values.
Returning a reference to a local variable is defined by the C++ standard as a "undefined behaviour". The standard often does this in cases where it may, for example, be difficult to determine that the value is indeed stack-based.
For example, consider:
class BBB
{
AAA& x;
public:
BBB(AAA& a) : x(a) {}
AAA& getX() { return x; }
};
AAA& getReg()
{
AAA aaa = { 2, 6}
BBB bbb(aaa);
return bbb.getX();
}
Most modern compilers will issue a warning for the scenario you have, and some may also give a warning for the code I just wrote. But it's almost certainly possible to come up with some more convoluted case for where it's NOT possible to diagnose this "error".
Upvotes: 7
Reputation: 1351
Unfortunately this is illegal code that invokes undefined behaviour, but it is not flagged as error by the compiler (although it might if more compiler diagnostics are enabled).
It happens to work by accident, presumably because the memory location where the object is created is not re-used for anything else, and is not cleared or overwritten, so you are just "lucky" that the values, once put there, remain.
Upvotes: 6
Reputation: 56921
It seems you want "proof" that it can fail. Maybe try:
int main() {
AAA &ref = getRef();
cout << "Hello, world!" << endl;
cout << ref.a << ", " << ref.b << endl;
}
also, you should enable and pay attention to your compiler's warnings.
Upvotes: 2