これが有効な C++ プログラムであることはわかっています。関数宣言のスローのポイントは何ですか? 私の知る限り、それは何もせず、何にも使用されていません。
#include <exception>
void func() throw(std::exception) { }
int main() { return 0; }
std::exception
から任意のものをスローでき、それ以外はスローできないことを指定しfunc()
ます。他の何かがスローされると、unexpected()
デフォルトで を呼び出す関数が呼び出されますterminate()
。
これが意味することは、何か他のものをスローすると、キャッチされない例外と同じようにほぼ確実にプログラムが終了するということですが、実装ではこれを強制する必要があります。try{...}catch(){...}
これは通常、 の周りにブロックを配置するのとほぼ同じfunc()
であり、パフォーマンスを阻害する可能性があります。
Guru of the Week のコラムによると、通常、例外仕様は価値がありません。Boostのガイドラインによるとthrows()
、非インライン関数の場合は空白にすることでわずかなメリットがあり、デメリットもあります。
これは例外仕様であり、ほぼ間違いなく悪い考えです。
func
が をスローする可能性がstd::exception
あり、その他の例外が発生func
すると が呼び出されると述べていunexpected()
ます。
これは C++ の例外仕様です。特定の関数が潜在的に型をスローすることを宣言しstd::exception
ます。
ただし、一般に、C++ の例外指定は避けるべき機能と見なされます。その動作はコンパイル時に宣言されますが、実行時にのみチェックされるという点で奇妙な機能です (たとえば、Java のバージョンとは大きく異なります)。
これは、機能を分解する良い記事です
基本的にこれ:
void func() throw(std::exception,B) { /* Do Stuff */}
これは単なる略記です:
void func()
{
try
{
/* Do Stuff */
}
catch(std::exception const& e)
{
throw;
}
catch(B const& e)
{
throw;
}
catch(...)
{
unexpected(); // This calls terminate
// i.e. It never returns.
}
}
スタックがアンワインドされず、RAII でのすべての努力が無駄になるため、terminate() の呼び出しが必要になることはめったにありません。このルールの唯一の例外は、空のスロー リストを宣言することです。これは主に、非スロー例外保証をサポートしていることを示す文書化の目的です (この状況でも、すべての例外を手動でキャッチする必要があります)。
非スローであるべきいくつかの重要な(imho)場所は、デストラクタと swap() メソッドです。デストラクタが非スローと明示的にマークされることはめったにありませんが、swap() は非スローとマークされることがよくあります。
void myNoThrowFunc() throws() // No-Throw (Mainlly for doc purposes).
{
try
{
/* Do Stuff */
}
catch(...) // Make sure it does not throw.
{
/* Log and/or do cleanup */
}
}
例外仕様。キーワードに続く型throw
は、関数がスローできるすべての例外 (存在する場合) を正確に指定します。ドラフトの 15.4 を参照してください。
注:例外指定のない関数は、すべての例外を許可します。例外指定が空の関数 は、例外をthrow()
許可しません。
これは例外仕様です。func() がスローできる唯一の例外は std::exception (またはその派生物) であると言われています。他の例外をスローしようとすると、代わりに std::unexpected が返されます。