Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ visualc&x2B+;尾部调用优化_C++_Visual Studio 2010_Tail Recursion_Tail Call Optimization_Tail Call - Fatal编程技术网

C++ visualc&x2B+;尾部调用优化

C++ visualc&x2B+;尾部调用优化,c++,visual-studio-2010,tail-recursion,tail-call-optimization,tail-call,C++,Visual Studio 2010,Tail Recursion,Tail Call Optimization,Tail Call,根据对该问题的答复: 看起来,编译器应该进行尾部递归优化 但我尝试过提出的选项,似乎编译器无法在模板函数的情况下进行优化。它能以某种方式修复吗?我不使用MS编译器,但GCC肯定可以对模板进行尾部递归优化。鉴于此功能: template <typename T> T f( T t ) { cout << t << endl; if ( t == 0 ) { return t; } return f( t - 1 ); } 模

根据对该问题的答复: 看起来,编译器应该进行尾部递归优化


但我尝试过提出的选项,似乎编译器无法在模板函数的情况下进行优化。它能以某种方式修复吗?

我不使用MS编译器,但GCC肯定可以对模板进行尾部递归优化。鉴于此功能:

template <typename T>
T f( T t ) {
   cout << t << endl;
   if ( t == 0 ) {
      return t;
   }
   return f( t - 1 );
}
模板
tf(T){

cout我在这里猜测,但可能需要手动操作

第一个填充模板使用递归填充缓冲区。 第二种方法使用手工制作的尾部递归来做同样的事情

由于某些原因,这可能不好,因此我建议谨慎使用

例如


是一个创建编译器的框架,它有一套广泛的优化机制(其中包括尾部调用优化)它提供C和C++编译器,虽然C++没有被考虑完成。< /P>你使用了什么G++选项?我的代码没有选择,没有做尾调用优化。@菲尔波恩G++-G-O2-壁-学究TR。cpp@NeilButterworth谢谢。为了获得汇编程序的内联源代码?@philcolbourn我发布的代码取自输出运行gdb调试器。在本例中使用Insight GUI。@Neil Butterworth啊!我想Linux的乐趣。我不认为Insight在苹果的特殊gdb上运行。
    5   T f( T t ) {
    6       cout << t << endl;
-   0x401362    <main+22>:      mov    %esi,0x4(%esp)
-   0x401366    <main+26>:      movl   $0x4740c0,(%esp)
-   0x40136d    <main+33>:      call   0x448620 <_ZNSolsEi>
-   0x401372    <main+38>:      mov    %eax,%ebx
    7      if ( t == 0 ) {
-   0x4013a5    <main+89>:      test   %esi,%esi
-   0x4013a7    <main+91>:      je     0x4013c8 <main+124>
    8         return t;
    9      }
    10     return f( t - 1 );
-   0x4013a9    <main+93>:      dec    %esi
-   0x4013aa    <main+94>:      jmp    0x401362 <main+22>
    11  }
#include <stdio.h>

template <class myType>

// fill a buffer with n v's

void fill( myType *p , int n , myType v ){
    if ( n <= 0 ) return;
    *p = v;
    fprintf( stderr , "[%x] = %d\n" , (unsigned) p , *p );
    fill( p+1 , n-1 , v );
}

template <class myType>

// fill a buffer with n v's

void fillTail( myType *p , int n , myType v ){
    tail:
    if ( n <= 0 ) return;
    *p = v;
    fprintf( stderr , "[%x] = %d\n" , (unsigned) p , *p );
    // hand crafted tail call
    p++;
    n--;
    goto tail;
}

int main(){
  int   buf[100];
  int   v = 12;
  fill( buf , 10 , v );
  for ( int i=0; i<10 ; i++ ){
    fprintf( stderr , "[%d] = %d\n" , i , buf[i] );
  }
  v = 13;
  fill( buf , 10 , v );
  for ( int i=0; i<10 ; i++ ){
    fprintf( stderr , "[%d] = %d\n" , i , buf[i] );
  }
}
fill:
        pushl   %ebp
LCFI0:
        movl    %esp, %ebp
LCFI1:
        subl    $24, %esp
LCFI2:
        cmpl    $0, 12(%ebp)
        jle     L4
        movl    8(%ebp), %edx
        movl    16(%ebp), %eax
        movl    %eax, (%edx)
        movl    12(%ebp), %edx
        decl    %edx
        movl    8(%ebp), %ecx
        addl    $4, %ecx
        movl    16(%ebp), %eax
        movl    %eax, 8(%esp)
        movl    %edx, 4(%esp)
        movl    %ecx, (%esp)
        call    fill
L4:
        leave
        ret

fillTail:
        pushl   %ebp
LCFI3:
        movl    %esp, %ebp
LCFI4:
        subl    $8, %esp
LCFI5:
        jmp     L6
L10:
        movl    8(%ebp), %edx
        movl    16(%ebp), %eax
        movl    %eax, (%edx)
        addl    $4, 8(%ebp)
        leal    12(%ebp), %eax
        decl    (%eax)
L6:
        cmpl    $0, 12(%ebp)
        jg      L10
L9:
        leave
        ret