Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

segfault in c++ templates

Tags:

c++

templates

I have a question about C++ templates. The following codes segfaults.

template <typename T1, typename T2>
inline T1 const& max(T1 const &a, T2 const &b) {
    return a < b ? b : a;
}
int main() {
    std::cout << max(4.9, 4) << std::endl;
}

However, remove the & and it does the right thing.

template<typename T1, typename T2>
inline T1 const max(T1 const &a, T2 const &b) {
    return a < b ? b : a;
}
int main() {
    std::cout << max(4.9, 4) << std::endl;
}

Furthermore, just use T instead of T1 and T2 and it works just fine.

template<typename T>
inline T const& max(T const &a, T const &b) {
    return a < b ? b : a;
} 

int main() {
    std::cout << max(4, 5) << std::endl;
}

What am I doing wrong here ?

like image 974
xGedaJastox Avatar asked Aug 25 '17 02:08

xGedaJastox


2 Answers

You should always compile with warnings turned on, see https://wandbox.org/permlink/KkhFOJw6QNJ7rv7J. If you had the warning flags on, the compiler would have helped you out and told you what you are doing wrong.

What is happening here is a promotion (see Return type of '?:' (ternary conditional operator)), you are executing a ternary expression on an int and a double. Doing that results in a temporary promoted double. And returning a reference to a temporary and referencing that after the function where its lifetime is bound returns is undefined behavior.

like image 149
Curious Avatar answered Sep 28 '22 05:09

Curious


In the two first, you are returning a reference to a temporary.

Why? Well, your function is returning the type T1, but you will have to convert one of the types you send. The conversion creates a temporary of the right type. Then you're returning it.

Since the temporary dies, the returned reference is bound to a dead object.

You already found a fix. You either not returning a reference, or you either take parameters of the same type.

If you look at the standard implementation, it chose the second solution: taking parameters of the same type.

like image 37
Guillaume Racicot Avatar answered Sep 28 '22 06:09

Guillaume Racicot