目前,在C++编译器中,尾调用优化的规则之一是返回类型必须是可平凡销毁的。(基于对GCC、Clang trunk行为的分析。MSVC在处理任何非平凡类型时都有问题)。
这个要求还有必要吗?随着C++17强制使用返回值优化,似乎即使返回类型是非平凡的,函数仍然可以使用尾调用优化。那么这里的问题是什么,阻止编译器实现这一点呢?
@编辑,代码示例:
#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
如果我正确理解汇编语言,应该可以用跳转指令来替换f()函数。
f
可以被g
替换(内联)(我猜这不是必须的)。而且由于g
有多个返回路径,所以它没有 NRVO(或 RVO)。 - alfCg
正确设置了$rax? - dyp