clang无限尾递归优化

时间:2013-08-28 01:37:35

标签: c++ tail-recursion clang++

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

%clang ++ -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总计

%g ++ -O2 test.cc

%。/ a.out 42 #infinte recursion

^ 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 ++的错误还是一个特征?

1 个答案:

答案 0 :(得分:7)

虽然g ++和clang ++都能够编译C ++ 98和C ++ 11代码,但clang ++从一开始就被设计为C ++ 11编译器,并且在其DNA中嵌入了一些C ++ 11行为(所以说话。)

使用C ++ 11,C ++标准变为线程感知,这意味着现在存在一些特定的线程行为。特别是1.10 / 24州:

  

实现可能假设任何线程最终将执行以下操作之一:

     

- 终止,

     

- 调用库I / O函数,

     

- 访问或修改易失性对象,或

     

- 执行同步操作或原子操作。

     

[注意:这是为了允许编译器转换,例如删除空循环,即使无法证明终止也是如此。 - 结束说明]

这正是clang ++在优化时所做的事情。它看到该函数没有副作用,即使它没有终止也将其删除