/EH
(Modelo de control de excepciones)
Especifica la compatibilidad del modelo de control de excepciones que genera el compilador. Los argumentos especifican si se debe aplicar catch(...)
la sintaxis tanto a las excepciones estructuradas como a las estándar de C++, si el código extern"C" se supone a throw las excepciones y si se deben optimizar determinadas comprobaciones noexcept
.
Sintaxis
/EHa
[-
]
/EHs
[-
]
/EHc
[-
]
/EHr
[-
]
Argumentos
a
Habilita el desenredado de la pila estándar de C++. Detecta las excepciones estructuradas (asincrónicas) y el estándar de C++ (sincrónicas) al usar la sintaxis catch(...)
. /EHa
invalida los argumentos /EHs
y /EHc
.
s
Habilita el desenredado de la pila estándar de C++. Detecta solo las excepciones estándar de C++ cuando se usa la sintaxis catch(...)
. A menos que también se especifique /EHc
, el compilador asume que las funciones declaradas como extern "C" pueden throw ser una excepción de C++.
c
Cuando se usa con /EHs
, el compilador asume que las funciones declaradas como extern "C" nunca throw son una excepción de C++. No tiene ningún efecto cuando se usa con /EHa
(es decir, /EHca
es equivalente a /EHa
). /EHc
se omite si no se especifica /EHs
o /EHa
.
r
Indica al compilador que genere siempre las comprobaciones de terminación en tiempo de ejecución para todas las funciones noexcept
. De forma predeterminada, las comprobaciones en tiempo de ejecución para noexcept
pueden optimizarse si el compilador determina que la función solo llame a funciones que no producen excepciones. Esta opción proporciona conformidad estricta con C++ a cambio de algún código adicional. /EHr
se omite si no se especifica /EHs
o /EHa
.
-
Borra el argumento de la opción anterior. Por ejemplo, /EHsc-
se interpreta como /EHs /EHc-
y es equivalente a /EHs
.
Los argumentos /EH
se pueden especificar por separado o combinados, en cualquier orden. Si se especifica más de una instancia del mismo argumento, la última invalidará las anteriores. Por ejemplo, /EHr- /EHc /EHs
es igual que /EHscr-
y /EHscr- /EHr
tiene el mismo efecto que /EHscr
.
Comentarios
Comportamiento del control de excepciones predeterminado
El compilador siempre genera el código que admite el control de excepciones estructuradas asíncronas (SEH). De manera predeterminada (es decir, si no se especifica ninguna opción /EHsc
, /EHs
o /EHa
), el compilador admite SEH controladores en la cláusula nativa de C++ catch(...)
. Sin embargo, también genera código que solo admite parcialmente las excepciones de C++. El código de desenredado de excepciones predeterminado no destruye los objetos de C++ automáticos fuera de los bloques try
que se salen del ámbito debido a una excepción. Las pérdidas de recursos y el comportamiento no definido pueden dar lugar cuando se produce una excepción de C++.
Control de excepciones estándar de C++
La compatibilidad total del compilador con el modelo de control de excepciones estándar de C++ que desenreda de forma segura los objetos de la pila requiere /EHsc
(recomendado), /EHs
o /EHa
.
Si usa /EHs
o /EHsc
, las cláusulas catch(...)
no detectarán catch las excepciones estructuradas asincrónicas. Las infracciones de acceso y las excepciones administradas System.Exception no se detectan. Además, cuando se produce una excepción asincrónica, los objetos en el ámbito no se destruyen, incluso si el código controla la excepción asincrónica. Este comportamiento es un argumento para no tratar las excepciones estructuradas no controladas. En cambio, considere estas excepciones como irrecuperables.
Cuando se usa /EHs
o /EHsc
, el compilador presupone que las excepciones solo pueden producirse en una instrucción throw
o en una llamada de función. Esto permite que el compilador elimine el código para realizar el seguimiento de vida útil de muchos objetos que no se pueden desenredar, lo que puede reducir significativamente el tamaño del código. Si usa /EHa
, la imagen ejecutable puede ser mayor y más lenta, ya que el compilador no optimiza try
los bloques de manera tan agresivamente. También deja en los filtros de excepción que limpian automáticamente los objetos locales, incluso si el compilador no ve ningún código que pueda producir throw una excepción de C++.
Control de excepciones estructurado y estándar de C++
La opción del compilador /EHa
permite el desenredado seguro de la pila tanto para las excepciones asincrónicas como para las excepciones de C++. Admite el control de las excepciones estándar de C++ y de las estructuradas mediante el uso de la cláusula nativa de C++ catch(...)
. Para implementar SEH sin especificar /EHa
, puede usar la sintaxis __try
, __except
y __finally
. Para más información, consulte Control de excepciones estructurado.
Importante
Especificar /EHa
e intentar controlar todas las excepciones mediante catch(...)
puede ser peligroso. En la mayoría de los casos, las excepciones asincrónicas son irrecuperables y podrían considerarse fatales. La detección y continuidad de estas excepciones puede dañar el proceso y generar errores que son difíciles de encontrar y corregir.
Aunque Windows y Visual C++ admiten SEH SEH, se recomienda encarecidamente que use el control de excepciones de C++, que se ajusta a la norma ISO (/EHsc
o /EHs
). Hace que el código sea más portable y flexible. Es posible que todavía haya ocasiones en las que tenga que usar SEH en código heredado o para determinados tipos de programas. Es necesario que el código compilado admita Common Language Runtime (/clr
), por ejemplo. Para más información, consulte Control de excepciones estructurado.
Se recomienda que nunca vincule los archivos objeto compilados con/EHa
otros compilados mediante /EHs
o /EHsc
en el mismo módulo ejecutable. Si tiene que controlar una excepción asincrónica mediante /EHa
en cualquier parte del módulo, use /EHa
para compilar todo el código del módulo. Puede usar la sintaxis de control de excepciones estructuradas en el mismo módulo que el código que se compila mediante /EHs
. Sin embargo, no se puede mezclar la SEH sintaxis con C++ try
, throw
y catch
en la misma función.
Use /EHa
si desea detectar catch una excepción producida por un método distinto de throw
. En este ejemplo se genera y se detecta una excepción estructurada:
// compiler_options_EHA.cpp
// compile with: /EHa
#include <iostream>
#include <excpt.h>
using namespace std;
void fail()
{
// generates SE and attempts to catch it using catch(...)
try
{
int i = 0, j = 1;
j /= i; // This will throw a SE (divide by zero).
printf("%d", j);
}
catch(...)
{
// catch block will only be executed under /EHa
cout << "Caught an exception in catch(...)." << endl;
}
}
int main()
{
__try
{
fail();
}
// __except will only catch an exception here
__except(EXCEPTION_EXECUTE_HANDLER)
{
// if the exception was not caught by the catch(...) inside fail()
cout << "An exception was caught in __except." << endl;
}
}
Control de excepciones en /clr
La opción /clr
implica /EHa
(es decir, /clr /EHa
es redundante). El compilador genera un error si /EHs
o /EHsc
se usa después de /clr
. Las optimizaciones no afectan a este comportamiento. Cuando se detecta una excepción, el compilador invoca los destructores de la clase para cualquier objeto que esté en el mismo ámbito que la excepción. Si no se detecta una excepción, estos destructores no se ejecutan.
Para obtener más información sobre las restricciones del control de excepciones en /clr
, consulte _set_se_translator.
Comprobaciones de las excepciones en tiempo de ejecución
La opción /EHr
fuerza las comprobaciones de terminación en tiempo de ejecución en todas las funciones que tienen un atributo noexcept
. De forma predeterminada, las comprobaciones en tiempo de ejecución se pueden optimizar si el back-end del compilador determina que una función solo llama a funciones que no inician . Dichas funciones se componen de cualquier función que tiene un atributo que especifica que no se puede producir ninguna excepción. Esto incluye las funciones marcadas como noexcept
, throw()
, __declspec(nothrow)
y cuando/EHc
se especifica las funciones extern "C"
. Las funciones que no producen excepciones también incluyen aquellas funciones que el compilador ha determinado que no producen excepciones durante la inspección. Se puede establecer explícitamente el valor predeterminado mediante /EHr-
.
Un atributo que no inicia no es una garantía de que una función no pueda producir excepciones. A diferencia del comportamiento de una noexcept
función, el compilador de MSVC considera una excepción producida por una función declarada mediante throw()
, __declspec(nothrow)
o extern "C"
como comportamiento indefinido. Las funciones que usan estos tres atributos de la declaración no imponen comprobaciones de terminación en tiempo de ejecución para las excepciones. Se puede usar la opción /EHr
para ayudar a identificar este comportamiento indefinido, al forzar al compilador para que genere las comprobaciones en tiempo de ejecución para las excepciones no controladas que eluden una función noexcept
.
Establecer la opción en Visual Studio o mediante programación
Para establecer esta opción del compilador en el entorno de desarrollo de Visual Studio
Abra el cuadro de diálogo Páginas de propiedades del proyecto. Para más información, vea Establecimiento del compilador de C++ y de propiedades de compilación en Visual Studio.
Seleccione Propiedades de configuración>C/C++>Generación de código.
Modifique la propiedad Habilitar excepciones de C++ .
O bien, establezca Habilitar excepciones de C++ en Noy, en la página de propiedades Línea de comandos , en el cuadro Opciones adicionales , agregue la opción del compilador.
Para establecer esta opción del compilador mediante programación
- Vea ExceptionHandling.
Consulte también
Opciones del compilador de MSVC
Sintaxis de la línea de comandos del compilador MSVC
Controlar errores y excepciones
Especificaciones de excepciones (throw)
Structured Exception Handling (C/C++)