C++ vs2010 c++;尾部调用优化

C++ vs2010 c++;尾部调用优化,c++,visual-studio-2010,visual-c++,tail-call-optimization,C++,Visual Studio 2010,Visual C++,Tail Call Optimization,考虑以下代码: 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; } 与 很奇怪

考虑以下代码:

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;
}

很奇怪,但是尾部调用优化消失了。据我记忆所及,在VS2008中没有这种奇怪的编译器行为。你知道为什么会发生这些事情,以及如何确保尾部调用优化完成了吗

);函数编译标志:/Ogtp

尝试了/O2和/Ox优化标志。还有其他重要的编译器选项吗


编辑:VS2012成功地进行了优化

尝试将函数显式
内联
–此外,您使用的优化级别是什么?

我不知道它是否有效,但如果。。。使用单返回语句的else:

return (x == 1) ? res : fac_aux( x - 1, res * x );

看起来很奇怪,你在做增量编译吗。 除此之外,编译器可能会被 多个参数,在工作版本中 只有一个参数,不知何故优化不再合格

您可以尝试将res参数设置为全局参数,我知道它很混乱 这种做法很糟糕,但可能会奏效

听起来像是编译器的错误/功能


/Tony

我尝试了以下代码

#include "stdafx.h"

int f( size_t i, int x )
{
    return ( ( i < 2 ) ? x : f( i - 1, i * x ) );
}

int f( size_t i )
{
    return ( f( i, 1 ) );
}

int _tmain(int argc, _TCHAR* argv[])
{
    {
        f( 0 );
    }

    return 0;
}
#包括“stdafx.h”
整数f(大小i,整数x)
{
收益率((i<2)x:f(i-1,i*x));
}
int f(尺寸i)
{
回报(f(i,1));
}
int _tmain(int argc,_TCHAR*argv[]
{
{
f(0);
}
返回0;
}

并使用了完整的优化/Ox,但我没有得到尾部递归。因此,MS VC++2010似乎不支持尾部递归

编译原始代码时,调用站点上的程序集具有部分内联的
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

不幸的是,内联没有帮助。尝试了/O2和/Ox标记在修改代码时,是否删除了
fac
函数?因此,未优化的函数实际上从未调用过?还是说fist函数中的tail调用?@Voivoid:该函数实际上是在程序集中调用的?(可能,但我想我会问)仅供参考。
/Ox
的“完全优化”这个名称有些欺骗性(至少在当代版本中是这样);实际上,使用
/O2
,您至少可以获得相同级别的优化(如果不是更多的话)。
#include "stdafx.h"

int f( size_t i, int x )
{
    return ( ( i < 2 ) ? x : f( i - 1, i * x ) );
}

int f( size_t i )
{
    return ( f( i, 1 ) );
}

int _tmain(int argc, _TCHAR* argv[])
{
    {
        f( 0 );
    }

    return 0;
}
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