2

Visual Studio 2012 の標準コンパイラの C++ プログラムにこのメソッドがあります。

bool FPS::frameRenderingQueued(const Ogre::FrameEvent &evt) {
    bool result = BaseApplication::frameRenderingQueued(evt);
    if (!result) {
        Ogre::LogManager::getSingleton().logMessage("Exiting, result of frame rendereing queued: " + result);
        return result;
    }
    for (int x = 0; x < 20; x++) {
        for (int z = 0; z < 20; z++) {
            robotAnimation[x][z]->addTime(evt.timeSinceLastFrame);
            tileSceneNode[x][z]->translate(tileSceneNode[x][z]->getOrientation() * Ogre::Vector3::UNIT_X * 35.0f * evt.timeSinceLastFrame);
        }
    }
}

エラーを出さずにコンパイルするにはどうすればよいでしょうか? 結果は予測できません。

実行すると、次のことが起こりました: 関数自体が返されました (Ogreが返さfalseれた場合にシャットダウンします。ただし、ブランチには到達していません。したがって、動作は予測できませんでした。frameRenderingQueued()falseif (!result) { ... }

後でreturn true;関数の最後に追加したとき、すべてが期待どおりに機能していました。

では、この壊れたメソッドを正常にコンパイルするにはどうすればよいでしょうか。

4

4 に答える 4

3

一般に、十分に複雑な関数が最後まで実行できるかどうかを静的解析で判断することは不可能であるため、コンパイラはそのエラーを診断する必要はありません。代わりに、未定義の動作が発生します。

この場合、警告を有効にしている場合、コンパイラが警告を表示することを願っています。

于 2013-10-16T10:09:28.967 に答える
2

警告をオフにしていますか?私にとって、VS2012 では、同様の関数が生成されます。

warning C4715: 'frameRenderingQueued' : not all control paths return a value

于 2013-10-16T10:10:27.660 に答える
1

動作は未定義です。これはコンパイラではエラーになるはずですが、決してそうではありません。コンパイラの警告をオンにする必要があります。

ここで未定義の動作である理由を正確に読んでください。 関数で戻り値が指定されていない場合、C++ プログラムはどのように戻り値を取得しますか?

于 2013-10-16T10:09:41.030 に答える
0

void 以外の関数の最後での実行は、未定義の動作です。つまり、コンパイラは診断を発行する必要がなく、必然的に最後まで実行する必要があることを証明できない限り、コードをコンパイルする必要がありますが、これは通常不可能です。(たとえば、 が BaseApplication::frameRenderingQueued常に を返すfalse、または呼び出した関数が tileSceneNode[x][z]->translate(...)常に例外をスローすることを想像してください。)

ほとんどのコンパイラは、上記のようなコードについて警告します。警告を有効にして、注意を払う必要があります。

于 2013-10-16T10:12:52.647 に答える