这里是一个简短的程序,用于计算整数的因子数量。该程序确实可以正确运行。然而,问题在于在当前Clang C++编译器(版本3.3,trunk 180686)的-O3
优化标志下,程序的行为会发生变化,结果不再正确。
代码
以下是代码:
#include <iostream>
constexpr unsigned long divisors(unsigned long n, unsigned long c)
{
// This is supposed to sum 1 anytime a divisor shows up
// in the recursion
return !c ? 0 : !(n % c) + divisors(n, c - 1);
}
int main()
{
// Here I print the number of divisors of 9 numbers! (from 1 to 9)
for (unsigned long i = 1; i < 10; ++i)
std::cout << i << " has " << divisors(i, i) << " divisors" << std::endl;
}
正确行为
下面是使用的编译命令,以及程序在正常情况下表现出的正确和期望输出:
clang++ -O2 -std=c++11 -stdlib=libc++ -lcxxrt -ldl sample.cpp -o sample
./sample
1 has 1 divisors
2 has 2 divisors
3 has 2 divisors
4 has 3 divisors
5 has 2 divisors
6 has 4 divisors
7 has 2 divisors
8 has 4 divisors
9 has 3 divisors
不正确的行为
使用以下命令行生成二进制文件会产生不正确的输出。请注意,唯一的更改是优化标志(-O2
更改为 -O3
)。
clang++ -O3 -std=c++11 -stdlib=libc++ -lcxxrt -ldl sample.cpp -o sample
./sample
1 has 1 divisors
2 has 2 divisors
3 has 2 divisors
4 has 1 divisors
5 has 2 divisors
6 has 3 divisors
7 has 2 divisors
8 has 2 divisors
9 has 2 divisors
编辑
我已经更新到主干版本,clang版本为3.4(主干183073)。行为不再重现,应该已经被修复了。如果有人知道问题是什么,如果确实已经验证并解决了问题,请随时提供答案。如果没有验证,可能会发生回归。