C++ 仕様は、C++ 仕様に含まれるもののみを定義できます。注意: C++ 仕様は、それが定義する仮想マシンの動作を定義します。そして、何かが起こり得ることを定義していない場合、それが起こり得るとは言っていない何かについての C++ の動作を定義していないことは確かです。
C++ 仕様によると、スレッドは正確に 3 つの方法で終了できます。つまり、メイン関数から戻る、メイン関数を介して例外をスローする、プロセスを直接終了する (std::terminate
または同様の関数と同様)。つまり、C++ スレッドは他の方法で終了することはできません。ExitThread
標準 C++ には関数はありません。同様に、std::thread
外部または内部でスレッドを強制終了することはできません。
したがって、C++ が発生しないと言うこのことを引き起こすものはすべて、定義上未定義です。「未定義の動作」でさえないと思います。C++ 11 が実際にスレッドの相互作用がどのように機能するかを規定する前に、スレッド化があったのはそのあいまいな空間でした。
同じことが「シグナル」にも当てはまります。C++ 仕様では、これらが関数を終了させる可能性があるとは述べていません。ここにドラゴンがいます。
に関してはlongjmp
、それは の動作によってカバーされlongjmp
ます。を使用して関数を終了すると、 と を使用しlongjmp
た場合と同様に、その関数は終了しません。また、C++ では、コンストラクターが完了したときにのみオブジェクトが構築されます。したがって、オブジェクトの初期化は完了せず、初期化されていません。throw
catch
私は ISO C 仕様 (C++ が の動作を参照している) を持っていませんが、 C++11 では、未定義の動作が発生する限り、/を/とlongjmp
同一視できることを強く推奨しています。throw
catch
longjmp
setjmp
§18.10 [support.runtime] p4:
この国際標準では、関数シグネチャ longjmp(jmp_buf jbuf, int val) の動作がより制限されています。setjmp/longjmp 呼び出しペアは、setjmp と longjmp を catch と throw で置き換えると、任意の自動オブジェクトに対して重要なデストラクタが呼び出される場合、未定義の動作になります。
だから私はこれが過小評価されているとは思わない。きれいに整頓されていないかもしれませんが、すべてのピースがそこにあります。