13

私は次のようなコードを持っています

try {
  doSomething();
} catch(InterruptException) {
  goto rewind_code;
}

if(0) {
rewind_code:
  longjmp(savepoint, 1);
}

私の質問は、C ++ランタイムによって保存される例外オブジェクトはgoto、catchブロックから出たときに解放されますか?または、ランタイムは、周囲の関数またはそのようなものが存在するまで、それをキャッシュすることを許可されていますか?上記のコードを複数回実行する場合、巻き戻しコードを取得するたびに、メモリがリークしないようにしたいだけです(longjmpコンパイラによって生成されたクリーンアップコードが関数プロローグ内またはその前に実行されないため)。

4

2 に答える 2

11

§6.6/2:

スコープから出ると(達成されたとしても)、デストラクタ(12.4)は、自動保存期間を持つすべての構築されたオブジェクトに対して呼び出されます...

少なくとも私が読んだように、「どのように達成されても」にはgoto.

編集:わかりました、ヨハネスのコメントに基づいて、私たちが気にかけているのは§15.1/4です:

例外に対して実行されている最後のハンドラーが、throw 以外の方法で終了したとき。一時オブジェクトが破棄され、実装によって一時オブジェクトのメモリの割り当てが解除される場合があります。

[ ... ]

破棄は、ハンドラーの例外宣言で宣言されたオブジェクトの破棄の直後に発生します。

于 2011-08-31T20:32:50.240 に答える
4

§ 15.1.4

例外オブジェクトのメモリは、3.7.4.1 で説明されている場合を除き、特定されていない方法で割り当てられます。ハンドラーが再スローによって終了した場合、制御は同じ例外の別のハンドラーに渡されます。例外オブジェクトは、例外の最後に残っているアクティブなハンドラーが再スロー以外の方法で終了した後、または例外オブジェクトを参照する型 std::exception_ptr (18.8.5) の最後のオブジェクトが破棄された後、いずれか遅い方で破棄されます。 . 前者の場合、 ハンドラーの例外宣言で宣言されたオブジェクト (存在する場合) の破棄の直後に、ハンドラーが終了するときに破棄が発生します。後者の場合、std::exception_ptr のデストラクタが戻る前に破棄が発生します。実装は、例外オブジェクトのメモリの割り当てを解除できます。そのような割り当て解除は、不特定の方法で行われます。

于 2011-08-31T20:57:31.330 に答える