例外の設計

例外の指定は、C++0x で使用が推奨されていない C++ 言語の機能です。これらは、関数からスローできる例外に関する概要情報を提供するように設計されていましたが、実際には、問題があることがわかりました。ある程度役に立つことがわかっている例外仕様は throw() 仕様です。次に例を示します。

void MyFunction(int i) throw();

関数が例外をスローしないようにコンパイラに指示します。これは、__declspec(nothrow) の使用と同じです。その使用は省略可能であると見なされます。C++0x では、noexcept 演算子が導入されますが、この機能は Visual Studio 2012 の時点ではまだ Visual C++ においてサポートされていません。

Visual C++ は、例外の仕様の実装に関して ANSI 標準から逸脱しています。次の表は、例外の仕様 Visual C++ 実装をまとめたものです。

例外の指定

説明

throw()

関数では例外はスローされません。ただし、例外が throw() でマークされた関数からスローされると、Visual C++ コンパイラは unexpected を呼び出しません (詳細については、unexpected (CRT)unexpected (<exception>) を参照してください)。関数が throw() でマークされている場合、Visual C++ コンパイラでは、関数が C++ 例外をスローせず、それに応じてコードも生成しないと想定します。関数が例外をスローする場合、(関数が C++ 例外をスローしないという仮定に基づいて) C++ コンパイラで実行される可能性のあるコード最適化が原因で、プログラムが正しく実行されないことがあります。

throw(...)

関数は、例外をスローできます。

throw(type)

関数は、型 type の例外をスローできます。ただし、Visual C++ .NET では、これは throw(...) として解釈されます。「関数の例外指定子」を参照してください。

例外処理がアプリケーションで使用されている場合、スローされた例外を処理する 1 つ以上の関数が必要です。例外をスローする関数と、例外を処理する関数の間に呼び出される関数は、例外をスローできる必要があります。

関数のスロー動作は、次の要因によって決まります。

  • C または C++ で関数をコンパイルするかどうか。

  • どの /EH コンパイラ オプションを使用するか。

  • 例外の仕様を明示的に指定するかどうか。

明示的な例外の指定は C 関数では使用できません。

次の表に、関数のスロー動作をまとめます。

Function

/EHsc

/EHs

/EHa

/EHac

C 関数

throw()

throw(...)

throw(...)

throw(...)

例外を指定していない C++ 関数

throw(...)

throw(...)

throw(...)

throw(...)

throw() 例外を指定した C++ 関数

throw()

throw()

throw(...)

throw(...)

throw(...) 例外を指定した C++ 関数

throw(...)

throw(...)

throw(...)

throw(...)

throw(type) 例外を指定した C++ 関数

throw(...)

throw(...)

throw(...)

throw(...)

使用例

// exception_specification.cpp
// compile with: /EHs
#include <stdio.h>

void handler() {
   printf_s("in handler\n");
}

void f1(void) throw(int) {
   printf_s("About to throw 1\n");
   if (1)
      throw 1;
}

void f5(void) throw() {
   try {
      f1();
   }
   catch(...) {
      handler();
    }
}

// invalid, doesn't handle the int exception thrown from f1()
// void f3(void) throw() {
//   f1();
// }

void __declspec(nothrow) f2(void) {
   try {
      f1();
   }
   catch(int) {
      handler();
    }
}

// only valid if compiled without /EHc 
// /EHc means assume extern "C" functions don't throw exceptions
extern "C" void f4(void);
void f4(void) {
   f1();
}

int main() {
   f2();

   try {
      f4();
   }
   catch(...) {
      printf_s("Caught exception from f4\n");
   }
   f5();
}
  

参照

関連項目

try、キャッチしてスローします (C++)をステートメント

C++ 例外処理