what is wrong with this code, why do I get wrong answer:
class X
{
private:
const int a;
const int& b;
public:
X(): a(10) , b(20)
{
// std::cout << "constructor : a " << a << std::endl;
// std::cout << "constructor : b " << b << std::endl;
}
void display()
{
std::cout << "display():a:" << a << std::endl;
std::cout << "display():b:" << b << std::endl;
}
};
int
main(void)
{
X x;
x.display();
return 0;
}
The above code will give me the result as
display():a:10
display():b:1104441332
But If I remove the commented 2 lines inside the default constructor it gives me proper result which is
constructor : a 10
constructor : b 20
display():a:10
display():b:20
please help, Thank you
You are initializing b
as a reference to a temporary.
The value 20
is created and exists only for the scope of the constructor.
The behavior of the code after this is very interesting - on my machine, I get different values from the ones you posted, but the fundamental behavior is still nondeterministic.
This is because when the value to which the reference points falls out of scope, it begins to reference garbage memory instead, giving unpredictable behavior.
See Does a const reference prolong the life of a temporary?; the answer https://stackoverflow.com/a/2784304/383402 links to the relevant section of the C++ standard, specifically the below text:
A temporary bound to a reference member in a constructor’s ctor-initializer
(12.6.2) persists until the constructor exits.
This is why you always get the right value in the print within the constructor, and rarely (but possibly sometimes!) after. When the constructor exits, the reference dangles and all bets are off.
I'll let my compiler answer this one:
$ g++ -std=c++98 -Wall -Wextra -pedantic test.cpp
test.cpp: In constructor 'X::X()':
test.cpp:9:26: warning: a temporary bound to 'X::b' only persists until the constructor exits [-Wextra]
$
You should turn on the warnings on your compiler as well.
b
refers to a temporary. What you have read (when printing) is an invalid location by the time it is read since the temporary 20
has technically gone out of scope.
To explain inconsistent results:
It is undefined behavior. What you see may be different if you:
x
You should always always avoid undefined behavior.
But why would the value change? Your reference likely refers to a stack address which has been rewritten (e.g. reused) by the time it's printed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With