Partilhar via


Exception Specifications

Exception specifications are a C++ language feature that is deprecated in C++11. They were designed to provide summary information about what exceptions can be thrown out of a function, but in practice they were found to be problematic. The one exception specification that did prove to be somewhat useful was the throw() specification. For example:

void MyFunction(int i) throw();

tells the compiler that the function does not throw any exceptions. It is the equivalent to using __declspec(nothrow). Its use is considered optional. In the ISO C++11 Standard, the noexcept operator is introduced, but support for this feature is not yet present in Visual C++.

Visual C++ departs from the ISO C++ Standard in its implementation of exception specifications. The following table summarizes the Visual C++ implementation of exception specifications:

Exception specification

Meaning

throw()

The function does not throw an exception. However, if an exception is thrown out of a function marked throw(), the Visual C++ compiler will not call unexpected (see unexpected (CRT) and unexpected (<exception>) for more information). If a function is marked with throw(), the Visual C++ compiler will assume that the function does not throw C++ exceptions and generate code accordingly. Due to code optimizations that might be performed by the C++ compiler (based on the assumption that the function does not throw any C++ exceptions) if a function does throw an exception, the program may not execute correctly.

throw(...)

The function can throw an exception.

throw(type)

The function can throw an exception of type type. However, in Visual C++ .NET, this is interpreted as throw(...). See Function Exception Specifiers.

If exception handling is used in an application, there must be one or more functions that handle thrown exceptions. Any functions called between the one that throws an exception and the one that handles the exception must be capable of throwing the exception.

The throw behavior of a function depends on the following factors:

  • Whether you are compiling the function under C or C++.

  • Which /EH compiler option you use.

  • Whether you explicitly specify the exception specification.

Explicit exception specifications are not allowed on C functions.

The following table summarizes the throw behavior of a function:

Function

/EHsc

/EHs

/EHa

/EHac

C function

throw()

throw(...)

throw(...)

throw(...)

C++ function with no exception specification

throw(...)

throw(...)

throw(...)

throw(...)

C++ function with throw() exception specification

throw()

throw()

throw(...)

throw(...)

C++ function with throw(...) exception specification

throw(...)

throw(...)

throw(...)

throw(...)

C++ function with throw(type) exception specification

throw(...)

throw(...)

throw(...)

throw(...)

Example

// 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();
}
About to throw 1
in handler
About to throw 1
Caught exception from f4
About to throw 1
in handler

See Also

Reference

try, throw, and catch Statements (C++)

C++ Exception Handling