lang无限尾递归优化
#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
% clang++ -O2 test.cc
%time ./a.out 42
% time ./a.out 42
1490723512
1490723512
./ a.out 42 0.00s用户0.00s系统69%cpu 0.004总计
./a.out 42 0.00s user 0.00s system 69% cpu 0.004 total
%time ./a.out 42
% time ./a.out 42
1564058296
1564058296
./ a.out 42 0.00s用户0.00s系统56%cpu 0.006总计
./a.out 42 0.00s user 0.00s system 56% cpu 0.006 total
%g ++ -O2 test.cc
% g++ -O2 test.cc
%./a.out 42#无限递归
% ./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.
那么它是bug还是clang ++的功能?
So is it a bug or a feature of clang++?
尽管g ++和clang ++都能够编译C ++ 98和C ++ 11代码,但是clang ++最初是作为C ++ 11编译器设计的,并且具有(可以这么说)一些C ++ 11行为嵌入其DNA中。
While both g++ and clang++ are able to compile C++98 and C++11 code, clang++ was designed from the start as a C++11 compiler and has some C++11 behaviors embedded in its DNA (so to speak).
有了C ++ 11,C ++标准就可以识别线程了,这意味着现在有了一些特定的线程行为。特别是1.10 / 24状态:
With C++11 the C++ standard became thread aware, and that means that now there are some specific thread behavior. In particular 1.10/24 states:
该实现可能假定任何线程最终都会执行以下操作之一:
The implementation may assume that any thread will eventually do one of the following:
-终止,
-调用库I / O函数,
— make a call to a library I/O function,
-访问或修改易失性对象,或者
— access or modify a volatile object, or
-执行同步操作或原子操作。
— perform a synchronization operation or an atomic operation.
[注意:这旨在允许编译器进行转换,例如删除空循环,即使无法证明终止也是如此。 —尾注]
[Note: This is intended to allow compiler transformations such as removal of empty loops, even when termination cannot be proven. — end note ]
这正是clang ++在优化时所做的。它看到该函数没有副作用,并且即使没有终止也将其删除。
And that is precisely what clang++ is doing when optimizing. It sees that the function has no side effects and removes it even if it does not terminate.