I'm not even sure about that. I "think" the intent is that
copying a dangling reference is undefined behavior (since the
intent is that references can be implemented as pointers, and
copying a dangling pointer is undefined behavior). And
formally, you copy the reference in the return statement,
*after* having "destructed" the local variables.
In practice, of course, even on a machine where copying dangling
pointers does cause a crash, it will work, because in practice, the
return value will be moved to its final location (probably a
register) before the memory on the stack is freed. So any
undefined behavior (if there is some) if you don't use the
return value is purely theoretical.
In the return expression an "int const&" reference is bound to
(initialized with) a temporary "int" that's initialized with the
"double", which is implicitly converted to int.
However, using the result of a call to foo() yields Undefined Behavior,
because you're returning a reference to a temporary. C++ is like that,
very permissive by default. It cheerfully lets you shoot yourself in
the groin, instead of arresting you[1], if that's what you say you want.
Thanks for the response. In the same context, does this code invoke
undefined behaviour ?
template <class T1, class T2>
const T1& max ( const T1& a, const T2& b )
{
return ( a > b ) ? a : b;
}
int main() {
int i = 20; double d = 40;
std::cout << max ( i, d ) << std::endl;
return 0;
}
Yes, although I almost missed it. That's a very bad definition
for max. Try:
template< typename T >
T const&
max( T const& a, T const& b )
{
return a > b ? a : b ;
}
You want the type conversion before calling the function, and in
cases of ambiguities like this one, you want the user to
explicitly specify what he wants, and not just automatically
take the type of the first argument.