Udostępnij za pośrednictwem


Specyfikacje wyjątków

Specyfikacje wyjątków to funkcja języka C++, którą w C ++11 uznano za przestarzałą.Zostały one zaprojektowane, aby podawać sumaryczne informacje o tym, jakie wyjątki mogą zostać wygenerowane z funkcji, ale w praktyce okazały się być problematyczne.Jedyna specyfikacja wyjątku, która miała jakiekolwiek zastosowanie, to specyfikacja throw().Na przykład:

void MyFunction(int i) throw();

informuje kompilator, że funkcja nie generuje żadnych wyjątków.Jest to równoważne użyciu __declspec(nothrow).Jego zastosowania są traktowane jako opcjonalne.W normie ISO C++ 11 wprowadzono operator noexcept, ale Visual C++ jeszcze nie obsługuje tej funkcji.

Visual C++ odbiega od standardu ISO C++ pod względem implementacji specyfikacji wyjątków. Poniższa tabela zawiera podsumowanie implementacji specyfikacji wyjątków w Visual C++:

Specyfikacja wyjątków

Znaczenie

throw()

Funkcja nie zgłasza wyjątku.Jednak jeśli wyjątek zostaje wyrzucony z funkcji oznaczonej throw(), kompilator języka Visual C++ nie wywoła nieoczekiwanego wyjątku (zobacz nieoczekiwany (CRT) i nieoczekiwany wyjątek (<exception>), aby uzyskać więcej informacji).Jeśli funkcja jest oznaczona przez throw(), kompilator języka Visual C++ założy, że ta funkcja nie generuje wyjątków C++ i odpowiednio wygeneruje kod.Ze względu na optymalizacje kodu, które mogą być wykonywane przez kompilator języka C++ (oparte na założeniu, że funkcja nie generuje żadnych wyjątków C++), jeśli funkcja zgłosi wyjątek, program nie może zostać poprawnie wykonany.

throw(...)

Funkcja może zgłosić wyjątek.

throw(type)

Funkcja może zgłosić wyjątek typu type.Jednak w programie Visual C++ .NET to jest interpretowane jako throw(...). Zobacz Specyfikatory wyjątku w funkcji.

Jeśli w aplikacji zastosowano obsługę wyjątków, musi istnieć przynajmniej jedna funkcja obsługująca wygenerowane wyjątki.Wszelkie funkcje wywołane między tą, która zgłosiła wyjątek, a tą, która obsługuje dany wyjątek, muszą być w stanie zgłaszać wyjątki.

Zachowanie zwracania wyjątku przez funkcję zależy od następujących czynników:

  • Czy kompilujesz funkcję w C lub C++.

  • Której opcji /EH kompilatora używasz.

  • Czy jawnie określasz wyjątek specyfikacji.

Jawne specyfikacje wyjątku nie są dozwolone w funkcjach C.

Poniższa tabela podsumowuje zachowanie zwracania wyjątku przez funkcję:

Funkcja

/EHsc

/EHs

/EHa

/EHac

Funkcja języka C

throw()

throw(...)

throw(...)

throw(...)

Funkcja języka C++ bez określenia wyjątków

throw(...)

throw(...)

throw(...)

throw(...)

Funkcja języka C++ z określeniem wyjątków throw()

throw()

throw()

throw(...)

throw(...)

Funkcja języka C++ z określeniem wyjątków throw(...)

throw(...)

throw(...)

throw(...)

throw(...)

Funkcja języka C++ z określeniem wyjątków throw(type)

throw(...)

throw(...)

throw(...)

throw(...)

Przykład

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

Zobacz też

Informacje

Instrukcje try, throw i catch (C++)

Obsługa wyjątków języka C++