/EH (Modelo de control de excepciones)
Especifica la compatibilidad del modelo de control de excepciones generada por el compilador. Los argumentos especifican si se debe aplicar la sintaxis a las excepciones de C++ tanto estructuradas como estándares, si se supone que el código catch(...)catch(...) es excepciones y si se deben optimizar throw determinadas noexcept comprobaciones.
Syntax
/EHa[-]
/EHs[-]
/EHc[-]
/EHr[-]
Argumentos
a
Habilita el desenredo de pila estándar de C++. Detecta excepciones estructuradas (asincrónicas) y estándar de C++ (sincrónicas) cuando se usa la catch(...) sintaxis . /EHa invalida los argumentos /EHs/EHc y .
s
Habilita el desenredo de pila estándar de C++. Detecta solo excepciones estándar de C++ cuando se usa la catch(...) sintaxis . A menos que también se especifique , el compilador asume que las funciones /EHc declaradas como /EHc pueden throw ser una excepción de C++.
c
Cuando se usa /EHs con , el compilador supone que las funciones declaradas como /EHs nunca son una throw excepción de C++. No tiene ningún efecto cuando se usa con /EHa (es /EHca decir, equivale a /EHa ). /EHc se omite si /EHs o /EHa no se especifican.
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 se pueden optimizar si el compilador determina que la función llama solo a funciones noexcept que no son de throw ing. Esta opción proporciona una conformidad estricta de C++ a costa de algo de código adicional. /EHr se omite si /EHs o /EHa no se especifican.
-
Borra el argumento de opción anterior. Por ejemplo, /EHsc- se interpreta como y es equivalente a /EHs /EHc-/EHs .
/EH Los argumentos se pueden especificar por separado o combinarse, en cualquier orden. Si se especifica más de una instancia del mismo argumento, la última invalida las anteriores. Por ejemplo, /EHr- /EHc /EHs es igual que y tiene el mismo efecto que /EHscr-/EHscr- /EHr/EHscr .
Comentarios
Comportamiento predeterminado del control de excepciones
El compilador siempre genera código que admite el control de excepciones estructurado asincrónico ( SEH ). De forma predeterminada (es decir, si no se especifica ninguna opción , o ), el compilador admite controladores /EHsc en la cláusula nativa de /EHs/EHaSEHcatch(...) C++. Sin embargo, también genera código que solo admite parcialmente excepciones de C++. El código de desenredado de excepciones predeterminado no destruye los objetos de C++ automáticos fuera de los bloques try -throw -and- catch -statements-cpp" data-linktype="relative-path">try que están fuera del ámbito debido a una excepción. Las pérdidas de recursos y el comportamiento indefinido pueden producirse cuando una excepción de C++ es throw n.
Control de excepciones estándar de C++
Compatibilidad completa del compilador con el modelo de control de excepciones de C++ estándar que desenreda de forma segura los objetos de pila /EHsc requiere (recomendado), /EHs o /EHa .
Si usa o , las cláusulas no tienen /EHs/EHsccatch(...)catch excepciones estructuradas asincrónicas. Las infracciones de acceso y las excepciones system.exception administradas no se detectan. Además, los objetos en el ámbito cuando se produce una excepción asincrónica no se destruyen, incluso si el código controla la excepción asincrónica. Este comportamiento es un argumento para dejar excepciones estructuradas no controladas. En su lugar, considere que estas excepciones son irreales.
Cuando se usa o , el compilador da por supuesto que las excepciones solo pueden producirse en /EHs una instrucción o en una llamada de /EHscthrow función. Esta suposición permite al compilador eliminar el código para realizar el seguimiento de la duración de muchos objetos desenredables, lo que puede reducir significativamente el tamaño del código. Si usa , la imagen ejecutable puede ser mayor y más lenta, ya que el compilador no optimiza los bloques /EHatry de forma tan agresiva. También deja filtros de excepción que limpian automáticamente los objetos locales, incluso si el compilador no ve ningún código que pueda ser throw una excepción de C++.
Control de excepciones de C++ estructurado y estándar
La /EHa opción del compilador habilita el desenredo de pila seguro para las excepciones asincrónicas y las excepciones de C++. Admite el control de las excepciones estándar de C++ y las excepciones estructuradas mediante la cláusula nativa de catch(...) C++. Para implementar SEH sin especificar , puede usar la /EHa__try sintaxis , y __except__finally . Para obtener más información, vea Control estructurado de excepciones.
Importante
Especificar y /EHa especificar para controlar todas las try excepciones mediante puede ser catch(...) 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 , se recomienda encarecidamente usar el control de excepciones SEH de C++ estándar ISO ( /EHsc o /EHs ). Hace que el código sea más portátil y flexible. Puede que haya veces que tenga que usar SEH en código heredado o para determinados tipos de programas. Es necesario en el código compilado para admitir Common Language Runtime ( /clr ), por ejemplo. Para obtener más información, vea Control estructurado de excepciones.
Se recomienda no vincular nunca los archivos de objeto compilados mediante a los /EHa compilados mediante /EHs o en el mismo módulo /EHsc ejecutable. Si tiene que controlar una excepción asincrónica mediante cualquier parte del /EHa módulo, use /EHa para compilar todo el código del módulo. Puede usar la sintaxis de control de excepciones estructurado en el mismo módulo que el código compilado mediante /EHs . Sin embargo, no se puede mezclar la SEH sintaxis con C++ try , y en la misma throwcatch función.
Use /EHa si desea una excepción que se produce por algo catch distinto de throw . Este ejemplo genera y catch es 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 /clr opción implica /EHa (es decir, /clr /EHa es redundante). El compilador genera un error si /EHs se usa o después de /EHsc/clr . Las optimizaciones no afectan a este comportamiento. Cuando se detecta una excepción, el compilador invoca los destructores de clase para los objetos que están en el mismo ámbito que la excepción. Si no se detecta una excepción, esos destructores no se ejecutan.
Para obtener información sobre las restricciones de control de excepciones /clr en , vea /clr.
Comprobaciones de excepciones en tiempo de ejecución
La /EHr opción 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 son de ing. Las funciones throw que no son de ing son funciones que tienen un atributo que especifica que ninguna excepción puede ser throw n. Incluyen funciones marcadas noexcept como throw() , , __declspec(nothrow) y, cuando se especifica , /EHcextern "C" funciones. Las funciones que no son de ing también incluyen las que el compilador ha determinado que no son throwthrow de inspección. Puede establecer explícitamente el comportamiento predeterminado mediante /EHr- .
Un atributo que no sea de ing no es una garantía de que una función no pueda throwthrow n las excepciones. A diferencia del comportamiento de una función, el compilador de MSVC considera una excepción n por una función declarada mediante noexcept , o como un comportamiento throwthrow()__declspec(nothrow)extern "C" indefinido. Las funciones que usan estos tres atributos de declaración no aplican comprobaciones de terminación en tiempo de ejecución para las excepciones. Puede usar la opción para ayudarle a identificar este comportamiento indefinido, forzando al compilador a generar comprobaciones en tiempo de ejecución para las excepciones no controladas que se escapen /EHr a una noexcept función.
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ónGeneración de código de C/C++.
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.
Consulta también
MSVC del compilador
MSVC sintaxis de la línea de comandos del compilador
Control de errores y excepciones
throw -cpp" data-linktype="relative-path">Exception specifications ( throw )
Structured Exception Handling (C/C++)