异常规范

异常规范是在 C++0x 弃用的 C++ 语言功能。 它们被设计用来提供有关哪些异常能被调用处函数外的摘要信息,但是实际上它们被发现有问题。 证明在某种程度上有用的异常规范是引发 () 规范。 例如:

void MyFunction(int i) throw();

告诉编译器此函数不引发任何异常。 它等效于使用 __declspec (nothrow)。 其使用被视为可选的。 在 C++0x 中,引入 noexcept 运算符,在 Visual Studio 2012 中支持此功能,但在 Visual C++中不支持此功能。

Visual C++ 保留在异常声明中实现的 ANSI 标准。 下表总结异常规范的 Visual C++ 实现:

异常规范

含义

引发()

该函数不引发异常。 但是,如果异常引发标记为 throw() 的函数,Visual C++ 编译器不会意外调用 (更多信息请参见unexpected (CRT)unexpected (<exception>) )。 如果用 throw() 标记函数,则Visual C++ 编译器假定该函数不引发 C++ 异常并相应生成代码。 由于可能由 C++ 编译器执行的编码优化 (基于假定函数不引发任何 C++ 异常),如果函数引发异常,该程序可能无法正确执行。

引发(...)

函数可以引发一个异常。

引发(type)

函数可以引发 type 的异常。 但是,在 Visual C++ .NET 中,该值被解释为 (...)。 请参见 Function Exception Specifiers(函数异常说明符)。

如果在应用程序中使用异常处理,一定有一个或多个函数处理引发的异常。 在引发异常函数和处理异常函数间的所有函数必须能够引发异常。

函数的调用行为基于以下因素:

  • 您是否在 C 或 C++ 下编译函数。

  • 您所使用的 /EH 编译器选项。

  • 是否显式指定异常规范。

不允许对 C 函数使用显式异常规范。

下表总结函数引发行为:

功能

/EHsc

/EHs

/EHa

/EHac

C 函数

引发()

引发(...)

引发(...)

引发(...)

没有异常规范的 C++ 函数

引发(...)

引发(...)

引发(...)

引发(...)

有 throw() 异常规范的 C++ 函数

引发()

引发()

引发(...)

引发(...)

有 throw (...) 异常规范的 C++ 函数

引发(...)

引发(...)

引发(...)

引发(...)

引发 (type) 异常声明的 C++ 函数

引发(...)

引发(...)

引发(...)

引发(...)

示例

// 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();
}
  

请参见

参考

尝试,捕获,并引发语句(C++)

C++异常处理