考虑以下代码:
int fac_aux( int x, int res ) {
if( x == 1 ) return res;
else return fac_aux( x - 1, res * x );
}
int fac( int x ) {
return fac_aux( x, 1 );
}
int main() {
int x = fac( 50 );
std::cout << x;
return 0;
}
根据生成的asm文件一切正常,尾部调用已优化。
尝试更换
int x = fac( 50 );
with
int x = fac_aux( 50, 1 );
很奇怪,但尾调用优化消失了。据我所知,VS2008中没有这种奇怪的编译器行为。有什么想法为什么会发生这些事情以及如何确保完成尾部调用优化吗?
;函数编译标志:/Ogtp
尝试了 /O2 和 /Ox 优化标志。还有其他重要的编译器选项吗?
Edit: VS2012设法做了优化
编译原始版本时,调用站点处的程序集具有部分内联fac_aux
,具体来说x - 1
部分,这是尾递归所必需的,但是使用fac_aux
防止部分内联,从而防止尾递归优化:
TestThin.fac_aux 013B1000 CMP ECX,1
013B1003 JE SHORT TestThin.013B100E
013B1005 IMUL EAX,ECX
013B1008 DEC ECX
013B1009 CMP ECX,1
013B100C JNZ SHORT TestThin.013B1005
013B100E RETN
013B100F INT3
TestThin.main 013B1010 MOV EAX,32
013B1015 LEA ECX,DWORD PTR DS:[EAX-1] ;notice the partial inlining of x - 1
013B1018 CALL TestThin.fac_aux
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)