#include <cstring>
// maximum of two values of any type (call-by-reference)
template<typename T>
T const& max (T const& a, T const& b)
{
return b < a ? a : b;
}
// maximum of two C-strings (call-by-value)
char const* max (char const* a, char const* b)
{
return std::strcmp(b,a) < 0 ? a : b;
}
// maximum of three values of any type (call-by-reference)
template<typename T>
T const& max (T const& a, T const& b, T const& c)
{
return max (max(a,b), c); // error if max(a,b) uses call-by-value
}
int main ()
{
auto m1 = ::max(7, 42, 68); // OK
char const* s1 = "frederic";
char const* s2 = "anica";
char const* s3 = "lucas";
auto m2 = ::max(s1, s2, s3); // run-time ERROR
}
$ g++ -o t2 t2.cpp
t2.cpp: In instantiation of ‘const T& max(const T&, const T&, const T&) [with T = const char*]’:
t2.cpp:30:29: required from here
t2.cpp:20:26: warning: returning reference to temporary [-Wreturn-local-addr]
return max (max(a,b), c);
^
Observation> The book says that the first statement(i.e. max(7, 42, 68)
works because those temporaries are created in main() where they persist until the
statement is done. However, I still have problems to understand why the first three-parameter max works while the second one failed.
Here are some experiments I have done and assume the following two functions are equivalent to two cases.
template<typename T>
T const& max (T const& a, T const& b, T const& c)
{
printf("%s\n", __PRETTY_FUNCTION__ );
const int& ab = max(a, b);
printf("address ab: %p\n", ab);
const int& abc = max(ab, c);
printf("address abc: %p\n", abc);
return abc;
}
output:
with T = int
version 1
address ab: 0x2
version 1
address abc: 0x3
template<typename T>
T const& max (T const& a, T const& b, T const& c)
{
printf("%s\n", __PRETTY_FUNCTION__ );
const char* ab = max(a, b);
printf("address ab: %p\n", ab);
const char* abc = max(ab, c);
printf("address abc: %p\n", abc);
throw 1; // throw here so that the compiler will be happy.
}
output:
with T = const char*
address s1: 0x4008da
address s2: 0x4008f3
address s3: 0x400909
version 2
address ab: 0x4008da
version 2
address abc: 0x400909
Question> I knew that you should not return a reference to a local variable defined within a function because that variable will not exist after the return of the function. Why the temporary variables in the first case were created in main function while the second case is defined within the function.