name keywords etiquetas description c++ visual-studio exception c++11 noexcept

c++ - keywords - seo html



¿Para qué sirve la excepción? (2)

Vi que C ++ 11 agregó la palabra clave noexcept . Pero realmente no entiendo por qué es útil.

Si la función se activa cuando no se supone que se debe lanzar, ¿por qué querría que el programa se bloquee?

Entonces, ¿cuándo debo usarlo?

Además, ¿cómo funcionará al compilar con / Eha y usar _set_se_translator ? Esto significa que cualquier línea de código puede lanzar una excepción de c ++, ya que podría lanzar una excepción SEH (debido al acceso a la memoria protegida) y se traducirá a la excepción de c ++.

¿Qué pasará entonces?


El uso principal de noexcept es para algoritmos genéricos, por ejemplo, al cambiar el tamaño de un std::vector<T> : para un algoritmo eficiente de elementos en movimiento, es necesario saber de antemano que ninguno de los movimientos se lanzará. Si los elementos en movimiento pueden lanzarse, los elementos deben copiarse en su lugar. Usando el noexcept(expr) , la implementación de la biblioteca puede determinar si una operación particular puede lanzar. La propiedad de las operaciones que no se lanzan se convierte en parte del contrato: si ese contrato se viola, todas las apuestas se cancelan y puede que no haya forma de recuperar un estado válido. Salir antes de causar más daño es la elección natural.

Para propagar el conocimiento sobre noexcept operaciones noexcept no lanzar, también es necesario declarar las funciones como tales. Para este fin, usaría noexcept , throw() o noexcept(expr) con una expresión constante. El formulario que usa una expresión es necesario al implementar una estructura de datos genérica: con la expresión se puede determinar si alguna de las operaciones dependientes del tipo puede generar una excepción.

Por ejemplo, std::swap() se declara algo como esto:

template <typename T> void swap(T& o1, T& o2) noexcept(noexcept(T(std::move(o1)) && noexcept(o1 = std::move(o2)));

Basándose en noexcept(swap(a, b)) la biblioteca puede elegir implementaciones de diferentes operaciones eficientes: si solo puede swap() sin arriesgar una excepción, puede violar invariantes temporalmente y recuperarlas más tarde. Si se produce una excepción, es posible que la biblioteca necesite copiar objetos en lugar de moverlos.

Es poco probable que la implementación de la biblioteca estándar de C ++ dependa de que muchas operaciones sean noexcept(true) . Las operaciones que probablemente verificará son principalmente aquellas involucradas en el movimiento de objetos, es decir:

  1. El destructor de una clase (tenga en cuenta que los destructores son por defecto noexcept(true) incluso sin ninguna declaración; si tiene un destructor que puede lanzar, debe declararlo como tal, por ejemplo: T::~T() noexcept(false) ).
  2. Los operadores de movimiento, es decir, la construcción de movimiento ( T::T(T&&) ) y la asignación de movimiento ( T::operator=(T&&) ).
  3. Las operaciones swap() ( swap(T&, T&) y posiblemente la versión miembro T::swap(T&) ).

Si alguna de estas operaciones se desvía del valor predeterminado, debe declararlo correspondientemente para obtener la implementación más eficiente. Las versiones generadas de estas operaciones declaran si están lanzando excepciones basadas en las operaciones respectivas usadas para miembros y bases.

Aunque puedo imaginar que algunas operaciones pueden ser agregadas en el futuro o por algunas bibliotecas específicas, probablemente no las operaciones de declaración como noexcept por ahora. Si surgen otras funciones que marcan la diferencia de no ser noexcept se pueden declarar (y posiblemente cambiar según sea necesario) en el futuro.


La razón por la que el programa puede fallar es porque noexcept le dice al optimizador que su código no se lanzará. Si lo hace, bueno, no hay forma de predecir qué sucederá con el código optimizado.

En cuanto a MSVC ++, tendrías que comprobar qué sucede cuando implementan noexcept . Desde un punto de vista estándar, SEH es un comportamiento indefinido. El acceso a la memoria protegida ya puede fallar ahora.