4

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;
    }
}

コンパイラは誤った最適化を実行しますか? または、最初のケースの動作が少なくとも予想外である特定の理由がありますか?

4

1 に答える 1