Namespaces
Variants

Exceptions

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

El manejo de excepciones proporciona una forma de transferir control e información desde algún punto en la ejecución de un programa a un manejador asociado con un punto previamente pasado por la ejecución (en otras palabras, el manejo de excepciones transfiere control hacia arriba en la pila de llamadas).

Evaluar una throw expresión lanzará una excepción. Las excepciones también pueden ser lanzadas en otros contextos .

Para que una excepción sea capturada, la expresión throw debe estar dentro de un try block , y el try block debe contener un handler que coincida con el tipo del objeto de excepción.

Al declarar una función, se puede proporcionar la(s) siguiente(s) especificación(es) para limitar los tipos de excepciones que una función puede lanzar:

(hasta C++17)
(desde C++11)

Los errores que surgen durante el manejo de excepciones son manejados por std::terminate y std::unexpected (hasta C++17) .

Contenidos

Uso

Mientras que la expresión throw puede utilizarse para transferir control a cualquier bloque de código en la pila de ejecución, por razones arbitrarias (similar a std::longjmp ), su uso previsto es el manejo de errores.

Manejo de errores

Lanzar una excepción se utiliza para señalar errores desde funciones, donde "errores" típicamente se limitan únicamente a lo siguiente [1] [2] [3] :

  1. Fallos en cumplir las postcondiciones, como no producir un objeto de retorno válido.
  2. Fallos en cumplir las precondiciones de otra función que debe ser llamada.
  3. (para funciones miembro no privadas) Fallos en (re)establecer un invariante de clase.

En particular, esto implica que los fallos de los constructores (ver también RAII ) y la mayoría de los operadores deben reportarse lanzando excepciones.

Además, las llamadas funciones de contrato amplio utilizan excepciones para indicar entradas inaceptables, por ejemplo, std::basic_string::at no tiene precondiciones, pero lanza una excepción para indicar índice fuera de rango.

Seguridad de excepciones

Después de que una función reporta una condición de error, pueden proporcionarse garantías adicionales con respecto al estado del programa. Generalmente se reconocen los siguientes cuatro niveles de garantía de excepción [4] [5] [6] , los cuales son superconjuntos estrictos entre sí:

  1. Garantía de excepción Nothrow (o nofail) — la función nunca lanza excepciones. Se espera Nothrow (los errores se reportan por otros medios o se ocultan) de los destructores y otras funciones que pueden ser llamadas durante el desenrollado de pila. Los destructores son noexcept por defecto. (desde C++11) Se espera Nofail (la función siempre tiene éxito) de los swaps, constructores de movimiento , y otras funciones utilizadas por aquellas que proporcionan garantía fuerte de excepción.
  2. Garantía fuerte de excepción — Si la función lanza una excepción, el estado del programa se revierte al estado justo antes de la llamada a la función (por ejemplo, std::vector::push_back ).
  3. Garantía básica de excepción — Si la función lanza una excepción, el programa se encuentra en un estado válido. No hay fugas de recursos y todas las invariantes de los objetos permanecen intactas.
  4. Sin garantía de excepción — Si la función lanza una excepción, el programa puede no estar en un estado válido: pueden haber ocurrido fugas de recursos, corrupción de memoria u otros errores que destruyan invariantes.

Los componentes genéricos pueden, además, ofrecer garantía de neutralidad ante excepciones : si se lanza una excepción desde un parámetro de plantilla (por ejemplo, desde el Compare objeto función de std::sort o desde el constructor de T en std::make_shared ), se propaga, sin cambios, al llamador.

Objetos de excepción

Mientras que objetos de cualquier tipo completo y punteros cv a void pueden ser lanzados como objetos de excepción, todas las funciones de la biblioteca estándar lanzan objetos anónimos por valor, y los tipos de esos objetos se derivan (directa o indirectamente) de std::exception . Las excepciones definidas por el usuario normalmente siguen este patrón. [7] [8] [9]

Para evitar la copia innecesaria del objeto de excepción y el object slicing, la mejor práctica para los manejadores es capturar por referencia. [10] [11] [12] [13]

Notas

Macro de prueba de características Valor Estándar Característica
__cpp_constexpr_exceptions 202411L (C++26) constexpr excepciones

Enlaces externos

  1. H. Sutter (2004) "Cuándo y cómo usar excepciones" en Dr. Dobb's
  2. H. Sutter, A. Alexandrescu (2004), "C++ Coding Standards", Ítem 70
  3. C++ Core Guidelines I.10: Use excepciones para señalar un fallo al realizar una tarea requerida
  4. B. Stroustrup (2000), "The C++ Programming Language" Apéndice E
  5. H. Sutter (2000) "Exceptional C++"
  6. D. Abrahams (2001) "Seguridad de Excepciones en Componentes Genéricos"
  7. D. Abrahams (2001) "Manejo de Errores y Excepciones"
  8. isocpp.org Super-FAQ "¿Qué debería lanzar?"
  9. C++ Core Guidelines E.14: Use tipos definidos por el usuario diseñados específicamente como excepciones (no tipos incorporados)
  10. C++ Core Guidelines E.15: Lanzar por valor, capturar excepciones de una jerarquía por referencia
  11. S. Meyers (1996) "More Effective C++" Ítem 13
  12. isocpp.org Super-FAQ "¿Qué debería capturar?"
  13. H. Sutter, A. Alexandrescu (2004) "C++ Coding Standards" Ítem 73