いいえ、クリティカル セクションに例外を残すことはできません。この場合は文句を言いませんが、クリティカル セクションのブロックの周りに暗黙的にg++
暗黙的に挿入します。try/catch
たとえば、次のコード:
#pragma omp critical (my_crit)
{
throw 3;
}
GCC 4.7 の OpenMP プロセッサによって次のように下げられます。
#pragma omp critical (my_crit)
__builtin_GOMP_critical_name_start (&.gomp_critical_user_my_crit);
try
{
D.20639 = __cxa_allocate_exception (4);
try
{
MEM[(int *)D.20639] = 3;
}
catch
{
__cxa_free_exception (D.20639);
}
__cxa_throw (D.20639, &_ZTIi, 0B);
}
catch
{
<<<eh_must_not_throw (terminate)>>>
}
__builtin_GOMP_critical_name_end (&.gomp_critical_user_my_crit);
暗黙的な組み込みの catch-all ハンドラーに到達すると<<<eh_must_not_throw (terminate)>>>
、非常に不自然な終了が発生します。
terminate called after throwing an instance of 'int'
Abort trap: 6
try/catch
外側の構成要素の存在に関係なく、暗黙的に挿入されます。つまり、例外がセクションtry/catch
を離れることはありません。critical
OpenMP 標準では、ほとんどの OpenMP コンストラクト ( parallel
、section
、master
、single
、for
、など) 内で例外がスローされた場合critical
、task
同じコンストラクト内で実行を再開し、同じスレッドが例外をキャッチする必要があることが義務付けられています。この制限に違反すると、非準拠の OpenMP コードが発生し、そのようなすべての構造内に終了ハンドラーを含むブロックをg++
挿入することによって、準拠が強制されます。try/catch
ステートメントが存在する場合のエラーに関してはreturn
、OpenMP は C/C++ で構造化されたブロックを次のように定義します。
C/C++ の場合、上部に 1 つのエントリがあり、下部に 1 つの出口がある実行可能ステートメント (場合によっては複合)、または OpenMP コンストラクト。
また (すべての言語で):
構造化ブロックからの分岐点を終了点にすることはできません。
単にブロックの底から落ちるのとは異なり、明らかreturn
にブロックの分岐を構成します。