C++ 標準では、例外をスローする with 関数の実行について次のように述べていstd::call_once
ます (§30.4.4.2/2)。
2/ 効果: 関数を呼び出さない call_once の実行は、受動的な実行です。func を呼び出す call_once の実行は、アクティブな実行です。アクティブな実行は、INVOKE (DECAY_COPY (std::forward(func))、DECAY_COPY (std::forward(args))...) を呼び出す必要があります。このような func の呼び出しで例外がスローされた場合、実行は例外的であり、それ以外の場合は戻ります。例外的な実行は、call_once の呼び出し元に例外を伝播します。任意の once_flag に対する call_once のすべての実行の中で、最大で 1 つが実行を返す必要があります。戻る実行がある場合、それは最後のアクティブな実行になります。戻り実行がある場合にのみ、パッシブ実行があります。[ 注: パッシブ実行により、他のスレッドは、以前に返された実行によって生成された結果を確実に観察できます。— エンドノート]
Visual Studio 2012 を使用して、次のコードを実行しています。
void f(){
throw std::exception( "Catch me!" );
}
int main( int argc, char* argv[] ){
once_flag flag;
try{
call_once( flag, f );
} catch( const std::exception& e ){
cout << e.what() << endl;
}
return 0;
}
私の結果は次のとおりです。catch ブロック内のコードが実行され、メッセージが出力されますが、プログラムが存在する場合、呼び出しが行われabort()
、次のメッセージが cout に出力されます。
...\mutex.c(38) ビジー中に破壊されたミューテックス
これは起こるはずですか?