如果有的话,C+编译器做尾递归优化?

如果有的话,C+编译器做尾递归优化?

在我看来,在C和C+中进行尾递归优化是非常好的,但是在调试过程中,我似乎从来没有看到过一个框架堆栈来表示这种优化。这很好,因为堆栈告诉我递归有多深。但是,优化也会很好。

有C+编译器做这个优化吗?为什么?为什么不行?

我该如何告诉编译器这样做呢?

  • 对于MSVC:

    /O2

    /Ox

  • GCC:

    -O2

    -O3

检查编译器是否在特定情况下完成了此操作如何?

  • 对于MSVC,使PDB输出能够跟踪代码,然后检查代码。
  • 为了GCC.?

我仍然会建议如何确定某个函数是否是由编译器像这样优化的(尽管我觉得它可以让Konrad让我放心地假定它)。

始终可以通过进行无限递归并检查它是否导致无限循环或堆栈溢出来检查编译器是否做到了这一点(我是与GCC一起这样做的,并发现-O2),但是我希望能够检查一个我知道无论如何都会终止的函数。我希望有一种简单的方法来检查这个:)


经过一些测试,我发现析构函数破坏了进行这种优化的可能性。有时候,更改某些变量和临时变量的作用域以确保它们在返回语句开始之前超出范围是值得的。

如果需要在尾调用之后运行任何析构函数,则无法进行尾调用优化。


繁花如伊
浏览 545回答 3
3回答

SMILET

GCC 4.3.2完全嵌入此函数(糟糕/琐碎)atoi()执行)main()..优化水平-O1..我注意到如果我玩弄它(甚至改变它static到extern,尾递归很快就会消失,所以我不会依赖它来获得程序的正确性。#include&nbsp;<stdio.h>static&nbsp;int&nbsp;atoi(const&nbsp;char&nbsp;*str,&nbsp;int&nbsp;n){ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(str&nbsp;==&nbsp;0&nbsp;||&nbsp;*str&nbsp;==&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;n; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;atoi(str+1,&nbsp;n*10&nbsp;+&nbsp;*str-'0');}int&nbsp;main(int&nbsp;argc,&nbsp;char&nbsp;**argv){ &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;!=&nbsp;argc;&nbsp;++i) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s&nbsp;->&nbsp;%d\n",&nbsp;argv[i],&nbsp;atoi(argv[i],&nbsp;0)); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}

九州编程

除了显而易见的(编译器不会进行这种优化,除非您需要它),C+:析构函数中的尾调用优化也很复杂。例如:&nbsp;&nbsp;&nbsp;int&nbsp;fn(int&nbsp;j,&nbsp;int&nbsp;i) &nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;<=&nbsp;0)&nbsp;return&nbsp;j; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Funky&nbsp;cls(j,i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;fn(j,&nbsp;i-1); &nbsp;&nbsp;&nbsp;}编译器不能(通常)对其进行尾调用优化,因为它需要调用cls&nbsp;后递归调用返回。有时编译器可以看到析构函数没有外部可见的副作用(因此可以提前完成),但通常不能。其中一个特别常见的形式就是Funky实际上是std::vector或者类似的。
打开App,查看更多内容
随时随地看视频慕课网APP