Currently, in C++ compilers one of the rules for tail-call optimization is that the return type must be trivially destructible. (Based on analyzing GCC, Clang trunk behavior. MSVC has troubles with any non-trivial types).
Is this requirement still necessary? With C++17 return-value-optimization being mandatory, it seems like the function could still use trail-call optimization, even when the return type is non-trivial. What is the problem here, that prevents compilers from that?
@edit, code example:
#include <string>
bool h();
std::string g() {
std::string s1 = "a", s2 = "b";
if (h()) return s1;
else return s2;
}
std::string f() {
return g(); // <= here I'd expect call-tail optimization due to RVO, since it is prvalue
}
https://godbolt.org/z/YYfMr6xdd
If I understand the assembly correctly, it should be possible to replace f() function with jump.