叮当无限尾递归优化
clang infinite tail recursion optimization
#include <iostream>
int foo(int i){
return foo(i + 1);
}
int main(int argc,char * argv[]){
if(argc != 2){
return 1;
}
std::cout << foo(std::atoi(argv[1])) << std::endl;
}
% 叮叮当当++ -O2 test.cc
% 时间 ./a.out 42
1490723512
./a.out 42 0.00s 用户 0.00s 系统 69% CPU 0.004 总计
% 时间 ./a.out 42
1564058296
./a.out 42 0.00s 用户 0.00s 系统 56% CPU 0.006 总计 0.006 总计
% g++ -O2 test.cc
% ./a.out 42 #infinte 递归
^C
% clang++ --version
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
% g++ --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
那么它是 clang++ 的错误还是功能?
虽然 g++ 和 clang++
都能够编译 C++98 和 C++11 代码,但 clang++ 从一开始就被设计为 C++11 编译器,并且在其 DNA 中嵌入了一些 C++11 行为(可以这么说(。
在 C++11 中,C++ 标准变得线程感知,这意味着现在有一些特定的线程行为。特别是 1.10/24 指出:
该实现可能假定任何线程最终都会执行以下操作之一:
— 终止,
— 调用库 I/O 函数,
— 访问或修改易失性对象,或
— 执行同步操作或原子操作。
[注意:这是为了允许编译器转换,例如删除空循环,即使无法证明终止。
而这正是 clang++ 在优化时所做的。它看到该函数没有副作用,即使它没有终止,也会将其删除。
相关文章:
- 将公共递归转换为尾递归,因为大型输入的堆栈溢出
- 尾递归函数未被 g++ 优化
- 尾递归,带有通过引用传递的向量
- 优化 BigInt 递归函数
- 优化递归问题以计算超级数字
- 如何使O(n)的函数检查字母(上和下)和()+-*/到尾递归?
- 带有对象的尾递归
- 优化此递归函数[Boggle resolver]
- 微优化-访问递归成员时的编译器优化
- 在turbo c++中,可以将一个普通递归函数转换为尾递归函数来对其进行优化
- 为什么当递归函数结果相乘时,g++ 仍然优化尾递归
- 在 C++ 中使用尾递归函数计算列表的总和
- 叮当无限尾递归优化
- constexpr函数求值可以做尾递归优化吗?
- 尾递归函数,用于计算数组中大于平均值的所有数字
- 将递归函数转换为尾递归函数
- 为什么下面的函数没有使用 Clang 生成尾递归?
- 已知的最有效的尾递归素数验证函数是什么?
- 在c++中做尾递归
- 模板元编程的尾递归性能