예외 사양
예외 사양은 C++0x에서 사라진 C++ 언어 기능입니다.그것들은 어떠한 예외를 하나의 함수 밖으로 던져 버릴 수 있을까라는 것에 관한 요약 정보를 제공하기 위하여 설계되었으나, 실제로 그것들은 문제가 있음이 발견되었습니다.어느 정도 유용한 것으로 입증된 예외 사양은 throw() 사양이었습니다.예를 들면 다음과 같습니다.
void MyFunction(int i) throw();
컴파일러에 함수가 예외를 throw하지 않도록 지시합니다.__declspec(nothrow)를 사용하는 것에 해당합니다.용도는 선택 사항으로 간주됩니다.C++0x에 noexcept 연산자가 소개되었지만 Visual Studio 2012의 Visual C++에서는 아직 이 기능을 지원하지 않습니다.
Visual C++는 예외 사항을 구현할 때 ANSI 표준을 사용합니다.다음 표는 예외 사양의 Visual C++ 구현을 요약합니다.
예외 사양 |
의미 |
---|---|
throw() |
이 함수는 예외를 throw하지 않습니다.그러나 throw()로 표시된 함수에서 예외가 throw되는 경우, Visual C++ 컴파일러는 unexpected를 호출하지 않습니다(자세한 내용은 unexpected (CRT) 및 unexpected (<exception>) 참조).함수에 throw()가 표시된 경우 Visual C++ 컴파일러는 함수가 C++ 예외를 throw하지 않고 그에 따라 코드를 생성한다고 가정합니다.함수가 예외를 throw하는 경우 C++ 컴파일러에서 수행할 수 있는 코드 최적화로 인해(함수가 C++ 예외를 throw하지 않는다는 가정을 전제) 프로그램이 정확하게 실행하지 못할 수 있습니다. |
throw(...) |
함수는 예외를 throw할 수 있습니다. |
throw(type) |
함수는 type 형식의 예외를 throw할 수 있습니다.하지만 Visual C++ .NET에서 이는 throw(...)로 해석됩니다.함수 예외 지정자를 참조하십시오. |
응용 프로그램에서 예외 처리를 사용하는 경우 throw된 예외를 처리하는 함수가 하나 이상 있어야 합니다.예외를 throw하고 예외를 처리하는 함수 사이에서 호출되는 모든 함수는 예외를 throw할 수 있어야 합니다.
동작을 throw하는 함수는 다음과 같은 요인에 따라 달라집니다.
C 또는 C++에서 함수를 컴파일하는지 여부
/EH 컴파일러 옵션을 사용합니다.
예외 사양을 명시적으로 지정하는지 여부
C 함수에서는 명시적 예외 사양이 허용되지 않습니다.
다음 표는 함수의 throw 동작을 요약합니다.
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();
}