これは、整数の約数を数える短いプログラムです。プログラムは正しく動作します。ただし、問題は、-O3
Clang C++ コンパイラ (バージョン 3.3、トランク 180686) の現在のトランクの最適化フラグの下では、プログラムの動作が変化し、結果が正しくないことです。
コード
コードは次のとおりです。
#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
to -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) に更新しました。この動作はもう再現されません。何らかの方法で既に修正されているはずです。実際に検証されて修正された問題があった場合は、問題が何であるかを知っている人は、お気軽に回答を提供してください。検証されたものがない場合、回帰が発生する可能性があります。