53

次のコードを検討してください。

void foo()
{
    {
        CSomeClass bar;

        // Some code here...

        goto label;

        // and here...
    }

label:
    // and here...
}

バーのデストラクタは呼び出されますか?

4

5 に答える 5

76

C++標準は次のように述べています。

スコープを終了すると(ただし、達成されます)、デストラクタ(12.4)は、そのスコープで宣言された自動ストレージ期間(3.7.2)のすべての構築済みオブジェクト(名前付きオブジェクトまたは一時オブジェクト)に対して、宣言の逆の順序で呼び出されます。

したがって、答えは「はい」です。

于 2010-07-05T13:47:42.533 に答える
35

はい、呼び出されます。

更新:( これを実行しても問題ありません。gotosは、ダミーの例外をスローしたり、bools / ifsを使用して問題を解決したりするよりも悪くありません。関数内の単純なgotoでは、スパゲッティコードにはなりません。)

于 2010-07-05T13:45:24.120 に答える
8

1)はい。2)これをしないでください。

精緻化:概念的には、これは。を介してループを残すことと同じbreakです。 gotoただし、強く、強くお勧めしません。を使用する必要はほとんどありませんgoto。何が起こっているのかを知るために、使用を精査する必要があります。

于 2010-07-05T13:44:48.037 に答える
7

はい、他のみんなが言うように。C++はこれを指定/義務付けています。

しかし、それに加えて、完全を期すために、一部のコンパイラ(gcc、clang、おそらく他のコンパイラで見つかったが、最後に知っていたMSVCを含まないgoto)で見つかった計算拡張機能を使用する場合、オブジェクトのデストラクタが呼び出されるかどうかはかなりあいまいです。が単一の場所に移動する場合、制御フロー転送の前にどのデストラクタを呼び出す必要があるかは非常に明確です。ただし、計算された場合、「期待される」セマンティクスを提供するために、さまざまなデストラクタを動的に呼び出す必要がある場合があります。そのような場合、この拡張機能を実装するコンパイラが何をするのかわかりません。これに遭遇したときの私の記憶は、計算されたときにclangが警告するということです-gotogotogotogotoデストラクタが呼び出されないと主張して、非自明なデストラクタを持つオブジェクトをスコープに残す可能性があります。うまくいく場合もあれば、そうでない場合もあります。他のコンパイラが何をしているのかわかりません。goto計算されたsを重要なデストラクタを持つオブジェクトと組み合わせて使用​​する場合は、この問題に注意してください。

于 2013-04-10T17:14:55.970 に答える
2

デストラクタは呼び出されることを意図していますが、gccにはバグがあることに注意してください。

コードが次の形式であり、クラスを返し、ジャンプを実行してクラスを破棄する場合、デストラクタはスキップされます。

CSomeClass foo()
{
    label:
    CSomeClass bar;

    // Some code here...

    if (someCondition)
       goto label; // if this jump is taken, bar is not destructed in gcc

    return bar;
}
于 2022-01-20T22:54:05.893 に答える