Sintaxis de Termination-Handler
Las palabras clave __try y __finally se usan para construir un controlador de terminación. En el ejemplo siguiente se muestra la estructura de un controlador de terminación.
__try
{
// guarded body of code
}
__finally
{
// __finally block
}
Para obtener ejemplos, consulte Uso de un controlador de terminación.
Al igual que con el controlador de excepciones, no se permite el bloqueo de __try y el bloque __finally requieren llaves ({}) y el uso de una instrucción goto para saltar a cualquiera de los bloques.
El bloque __try contiene el cuerpo protegido del código que está protegido por el controlador de terminación. Una función puede tener cualquier número de controladores de terminación y estos bloques de control de terminación se pueden anidar dentro de la misma función o en funciones diferentes.
El bloque __finally se ejecuta cada vez que el flujo de control sale del bloque __try . Sin embargo, el bloque __finally no se ejecuta si llama a cualquiera de las siguientes funciones dentro del bloque __try : ExitProcess, ExitThread o abort.
El bloque __finally se ejecuta en el contexto de la función en la que se encuentra el controlador de terminación. Esto significa que el bloque __finally puede acceder a las variables locales de esa función. La ejecución del bloque __finally puede finalizar por cualquiera de los siguientes medios.
- Ejecución de la última instrucción del bloque y continuación a la siguiente instrucción
- Uso de una instrucción de control (return, break, continue o goto)
- Uso de longjmp o salto a un controlador de excepciones
Si la ejecución del bloque de __try finaliza debido a una excepción que invoca el bloque de control de excepciones de un controlador de excepciones basado en fotogramas, el bloque de __finally se ejecuta antes de que se ejecute el bloque de control de excepciones. Del mismo modo, una llamada a la función de biblioteca en tiempo de ejecución de C de longjmp desde el bloque __try provoca la ejecución del bloque __finally antes de que la ejecución se reanude en el destino de la operación longjmp . Si __try la ejecución del bloque finaliza debido a una instrucción de control (return, break, continue o goto), se ejecuta el bloque __finally .
La función AbnormalTermination se puede usar dentro del bloque __finally para determinar si el bloque de __try finalizó secuencialmente, es decir, si alcanzó la llave de cierre (}). Dejar el bloque de __try debido a una llamada a longjmp, un salto a un controlador de excepciones o una instrucción return, break, continue o goto , se considera una terminación anómala. Tenga en cuenta que el error al finalizar secuencialmente hace que el sistema busque en todos los marcos de pila en orden inverso para determinar si se debe llamar a los controladores de terminación. Esto puede provocar una degradación del rendimiento debido a la ejecución de cientos de instrucciones.
Para evitar la terminación anómala del controlador de terminación, la ejecución debe continuar hasta el final del bloque. También puede ejecutar la instrucción __leave . La instrucción __leave permite la finalización inmediata del bloque de __try sin causar una terminación anómala y su penalización de rendimiento. Compruebe la documentación del compilador para determinar si se admite la instrucción __leave .
Si la ejecución del bloque __finally finaliza debido a la instrucción de control de retorno , equivale a un goto a la llave de cierre en la función envolvente. Por lo tanto, la función envolvente devolverá.