次のコードを検討してください。
void foo()
{
{
CSomeClass bar;
// Some code here...
goto label;
// and here...
}
label:
// and here...
}
バーのデストラクタは呼び出されますか?
次のコードを検討してください。
void foo()
{
{
CSomeClass bar;
// Some code here...
goto label;
// and here...
}
label:
// and here...
}
バーのデストラクタは呼び出されますか?
C++標準は次のように述べています。
スコープを終了すると(ただし、達成されます)、デストラクタ(12.4)は、そのスコープで宣言された自動ストレージ期間(3.7.2)のすべての構築済みオブジェクト(名前付きオブジェクトまたは一時オブジェクト)に対して、宣言の逆の順序で呼び出されます。
したがって、答えは「はい」です。
はい、呼び出されます。
更新:( これを実行しても問題ありません。gotosは、ダミーの例外をスローしたり、bools / ifsを使用して問題を解決したりするよりも悪くありません。関数内の単純なgotoでは、スパゲッティコードにはなりません。)
1)はい。2)これをしないでください。
精緻化:概念的には、これは。を介してループを残すことと同じbreak
です。 goto
ただし、強く、強くお勧めしません。を使用する必要はほとんどありませんgoto
。何が起こっているのかを知るために、使用を精査する必要があります。
はい、他のみんなが言うように。C++はこれを指定/義務付けています。
しかし、それに加えて、完全を期すために、一部のコンパイラ(gcc、clang、おそらく他のコンパイラで見つかったが、最後に知っていたMSVCを含まないgoto
)で見つかった計算拡張機能を使用する場合、オブジェクトのデストラクタが呼び出されるかどうかはかなりあいまいです。が単一の場所に移動する場合、制御フロー転送の前にどのデストラクタを呼び出す必要があるかは非常に明確です。ただし、計算された場合、「期待される」セマンティクスを提供するために、さまざまなデストラクタを動的に呼び出す必要がある場合があります。そのような場合、この拡張機能を実装するコンパイラが何をするのかわかりません。これに遭遇したときの私の記憶は、計算されたときにclangが警告するということです-goto
goto
goto
goto
デストラクタが呼び出されないと主張して、非自明なデストラクタを持つオブジェクトをスコープに残す可能性があります。うまくいく場合もあれば、そうでない場合もあります。他のコンパイラが何をしているのかわかりません。goto
計算されたsを重要なデストラクタを持つオブジェクトと組み合わせて使用する場合は、この問題に注意してください。
デストラクタは呼び出されることを意図していますが、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;
}