I am quite puzzled to see why the following piece of code successfully compiles and seems to run correctly by displaying 7 twice. I suspect there is some undefined behavior lurking in both invocations.
#include <iostream>
template <typename T>
const T& max(const T& x, const T& y)
{
return (x > y) ? x : y;
}
int main()
{
const int &var1 = max(3, 7);
std::cout << var1 << '\n';
int var2 = max(3, 7);
std::cout << var2 << '\n';
return 0;
}
Two local reference variables are referring to temporary values 3, 7, respectively, in this example. Then the method returns a reference to the maximum value, which is 7. But, when the method returns, the reference is no longer valid. It is dangling! So, even though var1 seems to refer to a value of 7, isn't it considered undefined with no guarantee that 7 will be there moments later?
Similarly, even though var2 is just supposed to get a copy of what comes out of max(), the return statement of that method returns a dangling reference! So, I think even var2 is unreliable because it grabs a copy from a garbage location.
So, should I consider that both cout statements display garbage (although 7 is displayed twice)?
In your example, using
var1exhibits undefined behavior, asvar1is a dangling reference. Usingvar2is fine.No, that's not what happens. The caller of
max()creates two temporaries, and passes references to them tomax().maxitself has no idea whether its arguments are references to temporaries, or to honest long-lived objects. So your examples are roughly equivalent to this:(Using an intermediate pointer here only because there's no syntax to delay binding a reference).