Windows 7 マシンで Visual Studio 2012 を使用していますが、次のコード スニペット (x64 モードでデフォルトの VC11 C++ コンパイラでコンパイル) を実行しようとすると、アサーションが失敗します。つまり、内側のループに入ることはありません。
void loopTest1()
{
const unsigned int k = 1;
for (int m=0; m<3; ++m)
{
int acc = 0;
for (int n=m-k; n<=m+k; ++n)
{
if (n<0 || n>=3) continue;
++acc;
}
assert (acc>0);
cout << "acc: " << acc << endl;
}
}
ここで、内側のループの終了条件を変更します。
void loopTest2()
{
const unsigned int k = 1;
for (int m=0; m<3; ++m)
{
int acc = 0;
int l = m+k; // this line was added
for (int n=m-k; n<=l; ++n) // m+k was replaced by l
{
if (n<0 || n>=3) continue;
++acc;
}
assert (acc>0);
cout << "acc: " << acc << endl;
}
}
次に、正しい結果が得られます。
acc: 2
acc: 3
acc: 2
をハードコードされた 1に置き換えると const unsigned int k
、それも機能します。
void loopTest3()
{
//const unsigned int k = 1;
for (int m=0; m<3; ++m)
{
int acc = 0;
for (int n=m-1; n<=m+1; ++n) //replaced k with 1
{
if (n<0 || n>=3) continue;
++acc;
}
assert (acc>0);
cout << "acc: " << acc << endl;
}
}
コンパイラは誤った最適化を実行しますか? または、最初のケースの動作が少なくとも予想外である特定の理由がありますか?