Partilhar via


Especificações de exceção

As especificações de exceção são um recurso da linguagem C++ que foi preterido no C++11. Elas foram criadas para fornecer informações resumidas sobre exceções que podem ser lançadas fora de uma função, mas na prática foi verificado que eram problemáticas. A especificação de uma exceção que provou ser um pouco útil era a especificação de throw(). Por exemplo:

void MyFunction(int i) throw();

informa o compilador que a função não lança exceções. É o equivalente a usar __declspec(nothrow). Seu uso é considerado opcional. No padrão ISO C++11, o operador noexcept é apresentado, mas o suporte para esse recurso não ainda está presente no Visual C++.

O Visual C++ parte do padrão ISO C++ em sua implementação de especificações de exceção. A tabela a seguir resume a implementação do Visual C++ de especificações de exceção:

Especificação de exceção

Significado

throw()

A função não gera uma exceção. No entanto, se uma exceção for lançada fora de uma função marcada como throw(), o compilador do Visual C++ não fará uma chamada inesperada (consulte unexpected (CRT) e unexpected (<exception>) para obter mais informações). Se uma função for marcada com throw(), o compilador Visual C++ assumirá que a função não lança exceções de C++ e gerará o código corretamente. Devido às otimizações de código que podem ser realizadas pelo compilador C++ (baseado na suposição de que a função não gera nenhuma exceção de C++) se uma função gerar uma exceção, o programa pode não executar corretamente.

throw(...)

A função pode gerar uma exceção.

throw(type)

A função pode gerar uma exceção do tipo type. No entanto, no Visual C++ .NET, isso é interpretado como throw(...). Consulte Especificadores de exceção de função.

Se a manipulação de exceção for usada em um aplicativo, deverá haver uma ou mais funções que tratam as exceções lançadas. Todas as funções chamadas entre a que lança uma exceção e aquela que lida com a exceção devem ser capazes de lançar a exceção.

O comportamento de lançamento de uma função depende dos fatores a seguir:

  • Se você estiver compilando a função em C ou C++.

  • Qual opção do compilador /EH você usa.

  • Se a especificação de exceção for determinada explicitamente.

As especificações explícitas de exceção não são permitidas em funções C.

A tabela a seguir resume o comportamento de lançamento de uma função:

Função

/EHsc

/EHs

/EHa

/EHac

Função C

throw()

throw(...)

throw(...)

throw(...)

Função C++ sem especificação de exceção

throw(...)

throw(...)

throw(...)

throw(...)

Função C++ com a especificação de exceção throw()

throw()

throw()

throw(...)

throw(...)

Função C++ com a especificação de exceção throw(...)

throw(...)

throw(...)

throw(...)

throw(...)

Função C++ com a especificação de exceção throw(type)

throw(...)

throw(...)

throw(...)

throw(...)

Exemplo

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

Consulte também

Referência

Instruções try, throw e catch (C++)

Tratamento de exceções C++