c-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
%时间./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#无限递归
^ 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的功能?
解决方法:
尽管g和clang都能够编译C 98和C 11代码,但是clang从一开始就被设计为C 11编译器,并且在其DNA中嵌入了一些C 11行为(可以这么说).
有了C 11,C标准就可以识别线程了,这意味着现在有了一些特定的线程行为.特别是1.10 / 24指出:
The implementation may assume that any thread will eventually do one of the following:
— terminate,
— 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在优化时正在做的事情.可以看到该函数没有副作用,即使没有终止也将其删除.
标签:c,clang-2,tail-recursion 来源: https://codeday.me/bug/20191013/1906477.html