Structured Exception Handling (C/C++)

El control estructurado de excepciones (SEH) es una extensión de Microsoft para C para controlar correctamente determinadas situaciones de código excepcionales, como errores de hardware. Aunque Windows y Microsoft C++ admiten SEH, se recomienda usar el control de excepciones de C++ estándar ISO. Hace que el código sea más portátil y flexible. Sin embargo, para mantener el código existente o para determinados tipos de programas, es posible que tenga que usar SEH.

Específico de Microsoft:

Gramática

try-except-statement :
__try compound-statement __except ( expression ) compound-statement

try-finally-statement :
__try compound-statement __finally compound-statement

Comentarios

Con SEH, puede asegurarse de que los recursos, como los bloques de memoria y los archivos, se liberan correctamente si la ejecución finaliza inesperadamente. También puede controlar problemas específicos(por ejemplo, memoria insuficiente) mediante el uso de código estructurado conciso que no se basa en instrucciones ni goto pruebas elaborados de códigos de retorno.

Las instrucciones y a las que se hace referencia en este artículo son extensiones try-except de Microsoft para el lenguaje try-finally C. Admiten SEH al permitir que las aplicaciones tomen el control de un programa después de que se produzcan eventos que de lo contrario finalizarían la ejecución. Aunque SEH funciona con archivos de código fuente de C++, no está diseñado específicamente para C++. Si usa SEH en un programa de C++ que se compila mediante la opción o /EHsc , se llama a los destructores de objetos locales, pero es posible que otro comportamiento de ejecución no sea el esperado. Para obtener una ilustración, vea el ejemplo más adelante en este artículo. En la mayoría de los casos, en lugar de SEH, se recomienda usar el control de excepciones de C++estándar ISO, que también admite el compilador de Microsoft C++. Mediante el control de excepciones de C++, puede asegurarse de que el código sea más portátil y puede controlar excepciones de cualquier tipo.

Si tiene código de C que usa SEH, puede mezclarlo con código de C++ que usa el control de excepciones de C++. Para obtener información, vea Controlar excepciones estructuradas en C++.

Existen dos mecanismos de SEH:

Estos dos tipos de controladores son distintos, pero están estrechamente relacionados a través de un proceso conocido como desenredo de la pila. Cuando se produce una excepción estructurada, Windows busca el controlador de excepciones instalado más recientemente que está activo actualmente. El controlador puede hacer una de tres cosas:

  • No reconocer la excepción y pasar el control a otros controladores.

  • Reconocer la excepción pero descartarla.

  • Reconocer la excepción y controlarla.

El controlador de excepciones que reconoce la excepción puede no estar en la función que se estaba ejecutando cuando se produjo la excepción. Puede estar en una función mucho más alta en la pila. La función que se está ejecutando actualmente y todas las demás funciones del marco de pila finalizan. Durante este proceso, la pila se desenlazada. Es decir, las variables locales no estáticas de las funciones terminadas se borran de la pila.

A medida que se desenreda la pila, el sistema operativo llama a cualquier controlador de terminación que haya escrito para cada función. Mediante el uso de un controlador de terminación, se limpian los recursos que, de lo contrario, permanecerán abiertos debido a una terminación anómala. Si ha escrito una sección crítica, puede salir de ella en el controlador de terminación. Cuando el programa se va a apagar, puede realizar otras tareas de mantenimiento, como cerrar y quitar archivos temporales.

Pasos siguientes

Ejemplo

Como se indicó anteriormente, se llama a los destructores de objetos locales si usa SEH en un programa de C++ y lo compila mediante la /EHa opción /EHsc o . Sin embargo, es posible que el comportamiento durante la ejecución no sea el esperado si también usa excepciones de C++. En este ejemplo se muestran estas diferencias de comportamiento.

#include <stdio.h>
#include <Windows.h>
#include <exception>

class TestClass
{
public:
    ~TestClass()
    {
        printf("Destroying TestClass!\r\n");
    }
};

__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
    printf("Throwing C++ exception\r\n");
    throw std::exception("");
#else
    printf("Triggering SEH exception\r\n");
    volatile int *pInt = 0x00000000;
    *pInt = 20;
#endif
}

__declspec(noinline) void TestExceptions()
{
    TestClass d;
    TestCPPEX();
}

int main()
{
    __try
    {
        TestExceptions();
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        printf("Executing SEH __except block\r\n");
    }

    return 0;
}

Si usa para compilar este código pero la macro de control de prueba local no está /EHscCPPEX definida, el TestClass destructor no se ejecuta. La salida es similar a esta:

Triggering SEH exception
Executing SEH __except block

Si usa para compilar el código y se define mediante (para que se produce una excepción de C++), se ejecuta el destructor y la salida /EHscCPPEX tiene el siguiente /DCPPEXTestClass aspecto:

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

Si usa para compilar el código, el destructor ejecuta si la excepción se produjo mediante o mediante SEH para /EHa desencadenar TestClass la std::throw excepción. Es decir, si CPPEX está definido o no. La salida es similar a esta:

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

Para obtener más información, vea (Modelo de control de excepciones).

FIN de Específicos de Microsoft

Consulte también

Control de excepciones
Palabras clave
<exception>
Errores y control de excepciones
Control estructurado de excepciones (Windows)