0

このコードがエラーなしで実行されないのはなぜですか? bad_exception予期しない例外が発生したときに自動的に呼び出されるはずではありませんか? または、そのハンドラーを設定する必要がありますか?

#include <iostream>
#include <exception>
using namespace std;
class C{};
void test() throw(bad_exception)
{
    throw C();
}
int main()
{
    try
    {
         test();
    } catch(bad_exception& e)
    {
        cout << "Caught ";
    }
}
4

4 に答える 4

3

C ++ 03理論 の場合:例外仕様にない例外をスローすると、unexpected()が呼び出されます。これを介して予期しないハンドラーを設定していない場合は、set_unexpected()これterminate()が呼び出されます。これは、観察した場合です。終了を呼び出さないが例外をスローする予期しないハンドラー設定し、その例外が例外仕様にリストされていない場合、それはbad_exceptionに変換されます。したがって、期待される結果を得るには、set_unexpected()最初に適切なハンドラーを使用して呼び出します。

C ++ 03の実践では: 一部のコンパイラは(以外のthrow())例外仕様をまったくサポートしていませんが、他のコンパイラはそれらが正しいかどうかを評価/チェックしていません。Herb Sutterが指摘しているように、例外仕様は、正しく処理するのが容易ではない不器用な「シャドウタイプシステム」を作成します(可能であれば)。したがって..

... C ++ 11の場合: 例外仕様は非推奨になりました。むしろそれらを使用するべきではありません。ただし、nothrow機能が少し異なる演算子がありますthrow()


PS:では、なぜC++03にstd::bad_exceptionがあるのですか? コードには3つの異なる領域があります。

  • 例外仕様を作成している関数。
  • その関数から呼び出している「外部」コードで、仕様に一致しない例外をスローする場合とスローしない場合があります。
  • (おそらく未知の)予期しないハンドラー。これは何でもかまいません。プログラムを終了/終了/中止するか、何かをスローする必要があります。

したがって、「外部」コードが例外仕様に違反する例外をスローした場合、次の3つの結果が考えられます。

  1. ハンドラーはプログラムを終了します。関数に独自のハンドラーを設定しない限り、それについてできることはあまりありません。
  2. ハンドラーは、例外仕様に一致する例外をスローします。そして、すべてが順調です。
  3. ハンドラーは何か他のものをスローします。ランタイムに今何をさせたいですか?そこでbad_exceptionが登場します。仕様に含まれている場合、「何か他のもの」がbad_exceptionに変換され、プログラムが続行されます。そうでない場合は、terminateが呼び出されます。

関数内に独自のハンドラーを設定すると、関数を使用したいだけの人が以前に設定したハンドラーが無効になります。彼はあなたが彼のハンドラーを無効にすることを期待しません。さらに、ハンドラーはグローバルなwhat-happens-ifポリシーとして意図されているため、単一の関数の実装では気にする必要はありません。

于 2012-11-27T09:31:36.830 に答える
2

スローされた例外は例外仕様の一部ではないため、これstd::unexpectedはデフォルトで which を呼び出す必要があります。std::terminate()

(ここでは、Linux では g++、 Solaris ではSun Oracle CC、AIX BTW では IBM xlC で行います)

予期しないハンドラーをインストールすると、期待どおりに動作します。

include <iostream>
#include <exception>
using namespace std;
class C{};

void myunexpected()
{
    throw std::bad_exception();
}

void test() throw(std::bad_exception)
{
    throw C();
}
int main()
{
    try
    {
        set_unexpected(myunexpected);
        test();
    } catch(std::bad_exception& e)
    {
        std::cout << "Caught ";
    }
}
于 2012-11-27T09:15:33.210 に答える
1

[except.unexpected] に従って、関数が動的例外仕様にリストされていない例外をスローすると、std::unexpected()が呼び出されます。[unexpected.handler] によると、std::unexpected()単純に のデフォルトの実装はstd::terminate().

ただし、プログラムは、例外を (再) スローできる独自のハンドラーをインストールできます。このようにスローされた例外が動的例外仕様で許可されていない場合は、それが許可されているstd::bad_exception場合に置き換えることできます。

于 2012-11-27T09:24:17.893 に答える
0

あなたの catch-block は、 typebad_exceptionまたはそのサブタイプの例外のみをキャッチします。Cこの基準を満たしていません。

実際、この質問はあなたの質問と非常によく似ています。受け入れられた回答は、関数が仕様に一致しない例外をスローした場合 (存在する場合)、std::unexpectedが呼び出され、デフォルトで が呼び出されることを説明していますstd::terminate

于 2012-11-27T09:14:53.917 に答える