try
block
exception が try ブロック内でスローされた場合、関連付けられたハンドラによって処理される可能性があります。
目次 |
構文
try
複合文
ハンドラシーケンス
|
(1) | ||||||||
try
コンストラクタ初期化子
(オプション)
複合文
ハンドラシーケンス
|
(2) | ||||||||
| compound-statement | - | a 複合文 |
| handler-seq | - | 空でない ハンドラ のシーケンス |
| ctor-initializer | - | メンバ初期化子リスト( コンストラクタ 専用) |
通常の try ブロック
通常の try ブロックは 文 です。
例外がその compound-statement からスローされた場合、その例外は handlers 内の handler-seq と照合されます:
void f() { throw 1; // 以下のハンドラでは処理されない try { throw 2; // 関連付けられたハンドラで処理される } catch (...) { // 例外2を処理する } throw 3; // 上記のハンドラでは処理されない }
関数 try ブロック
関数 try ブロックは、特別な種類の 関数本体 です。
例外がその compound-statement または ctor-initializer (存在する場合)からスローされた場合、その例外は handlers 内の handler-seq と照合されます:
int f(bool cond) { if (cond) throw 1; return 0; } struct X { int mem; X() try : mem(f(true)) {} catch (...) { // 例外1を処理します } X(int) try { throw 2; } catch (...) { // 例外2を処理します } };
静的 ストレージ期間 を持つオブジェクトのデストラクタ、または静的ストレージ期間を持つ 非ブロック変数 に関連付けられたオブジェクトのコンストラクタでスローされた例外は、 main 関数 の関数 try ブロックでは捕捉されません。
|
スレッドストレージ期間を持つオブジェクトのデストラクタ、またはスレッドストレージ期間を持つ非ブロック変数に関連付けられたオブジェクトのコンストラクタでスローされた例外は、スレッドの初期関数の関数 try ブロックでは捕捉されません。 |
(C++11以降) |
関数の compound-statement の終端から抜け出すことは、 handler の try ブロックの終端から抜け出すことと等価です。ただし、その関数がコンストラクタまたはデストラクタである場合を除きます(下記参照)。
コンストラクタとデストラクタ try ブロック
クラス
C
について、そのコンストラクタまたはデストラクタの定義の関数本体が関数
try
ブロックである場合、そして例外がそれぞれ
C
のサブオブジェクトの初期化中または破棄中にスローされると、その例外は関数
try
ブロックの
handler-seq
内の
ハンドラ
とも照合されます:
int f(bool cond = true) { if (cond) throw 1; return 0; } struct X { int mem = f(); ~X() { throw 2; } }; struct Y { X mem; Y() try {} catch (...) { // 例外1を処理 } ~Y() try {} catch (...) { // 例外2を処理 } };
オブジェクトのコンストラクタまたはデストラクタの関数 try ブロックハンドラ内で、そのオブジェクトの非静的メンバまたは基底クラスを参照すると、未定義動作を引き起こします。
コンストラクタの関数 try ブロックのハンドラ内で return 文 が現れた場合、プログラムは不適格となります。
コンストラクタまたはデストラクタの関数 try ブロックのハンドラの終端に制御が到達した場合、 現在処理中の例外 が再スローされます。
制御フロー
compound-statement は try ブロックの control-flow-limited statement です:
void f() { goto label; // エラー try { goto label; // OK label: ; } catch (...) { goto label; // エラー } }
ジャンプ文
(jump statement)
(
goto
,
break
,
return
,
continue
) を使用して、
try
ブロック(およびそのハンドラを含む)から制御を転送することができます。これが発生すると、
try
ブロック内で宣言された各変数は、その宣言を直接含むコンテキストで破棄されます:
try { T1 t1; try { T2 t2; goto label; // 最初にt2を破棄し、その後t1を破棄 } catch(...) { // t2の破棄中に例外がスローされた場合に実行 } } catch(...) { // t1の破棄中に例外がスローされた場合に実行 } label: ;
キーワード
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| CWG 98 | C++98 |
switch
文が制御を
compound-statement 内の try ブロックに 転送可能であった |
禁止 |
| CWG 1167 | C++98 |
デストラクタの関数
try
ブロックが
基底クラスまたはメンバのデストラクタからの 例外を捕捉するかどうかが未規定であった |
そのような例外は
捕捉される |