如果有的话,哪些C ++编译器会做尾巴
在我看来,它可以非常好地在C和C ++中进行尾递归优化,但在调试时我似乎没有看到指示此优化的帧堆栈。 这很好,因为堆栈告诉我递归有多深。 但是,优化也会很好。
是否有任何C ++编译器可以做这种优化? 为什么? 为什么不?
我该如何去告诉编译器这样做?
如何检查编译器是否在特定情况下完成了这项工作?
我仍然会对如何确定某个函数是否由编译器进行优化提供建议(即使我发现康拉德让我承认它)
总是可以通过无限递归检查编译器是否执行此操作,并检查它是否导致无限循环或堆栈溢出(我使用GCC进行了此操作并发现-O2已足够),但我想要能够检查某个我知道会终止的函数。 我很想有一个简单的方法来检查这:)
经过一些测试后,我发现破坏者破坏了进行此优化的可能性。 有时可能需要更改某些变量和临时对象的范围,以确保它们在返回语句开始之前超出范围。
如果在尾部呼叫后需要运行任何析构函数,则不能进行尾部呼叫优化。
当前版本的VC ++和GCC都相当好地调用了优化,甚至用于相互递归调用。 我敢打赌英特尔编译器也是。
让编译器进行优化很简单:只需打开优化速度即可。 但是你仍然这样做,对吧? ;-)
检查编译器是否执行了优化(我知道)的最简单方法是执行调用,否则会导致堆栈溢出 - 或者查看程序集输出。 但是,你通常不会假设编译器进行了优化。
/编辑:在Mark Probst的毕业论文过程中,C语言的尾部呼叫优化已被添加到GCC中。 论文描述了实施中的一些有趣的注意事项。 值得一读。
gcc 4.3.2完全将这个函数(蹩脚/简单的atoi()
实现)内联到main()
。 优化级别是-O1
。 我注意到如果我玩弄它(即使将它从static
变为extern
,尾部递归也会很快消失,所以我不会依赖它来保证程序的正确性。
#include <stdio.h>
static int atoi(const char *str, int n)
{
if (str == 0 || *str == 0)
return n;
return atoi(str+1, n*10 + *str-'0');
}
int main(int argc, char **argv)
{
for (int i = 1; i != argc; ++i)
printf("%s -> %dn", argv[i], atoi(argv[i], 0));
return 0;
}
大多数编译器在调试版本中不做任何优化。
如果使用VC,尝试使用启用PDB信息的版本构建 - 这将让您通过优化的应用程序进行追踪,并且您应该有希望看到您想要的内容。 但是,请注意,调试和跟踪经过优化的版本会在各处跳跃,并且通常不能直接检查变量,因为它们只会在寄存器中结束或完全被优化。 这是一个“有趣”的体验......
链接地址: http://www.djcxy.com/p/80537.html上一篇: Which, if any, C++ compilers do tail
下一篇: F# recursive bind in computational expressions and tail recursiveness