Instrucción try-finally

La instrucción try-finally es una extensión específica de Microsoft que admite el manejo estructurado de excepciones en los lenguajes C y C++.

Sintaxis

La sintaxis siguiente describe la instrucción try-finally:

    // . . .
    __try {
        // guarded code
    }
    __finally {
        // termination code
    }
    // . . .

Grammar

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

La instrucción try-finally es una extensión de Microsoft a los lenguajes C y C++ que permite que las aplicaciones de destino garanticen la ejecución del código de limpieza cuando se interrumpe la ejecución de un bloque de código. La limpieza consta de tareas como desasignar memoria, cerrar archivos y liberar identificadores de archivo. La instrucción try-finally es especialmente útil para las rutinas que tienen varios lugares donde comprobar un error, lo que puede causar que la rutina termine antes de tiempo.

Para obtener información relacionada y un ejemplo de código, consulte la Instrucción try-except. Para obtener más información sobre el control de excepciones estructurado en general, consulte Control de excepciones estructuradas. Para obtener más información sobre cómo se controlan las excepciones en aplicaciones administradas con C++/CLI, consulte Control de excepciones con /clr.

Nota:

El control de excepciones estructurado funciona con Win32 para archivos de código fuente de C y C++. Sin embargo, no está diseñado específicamente para C++. Para asegurarse de que el código será más portable, use el control de excepciones de C++. Además, el control de excepciones de C++ es más flexible, ya que puede controlar excepciones de cualquier tipo. Para los programas de C++, se recomienda usar el mecanismo de control de excepciones de C++ (try, catch y throw).

La instrucción compuesta detrás de la cláusula __try es la sección protegida. La instrucción compuesta detrás de la cláusula __finally es el controlador de terminación. El controlador especifica un conjunto de acciones que se ejecutan cuando se sale de la sección protegida, ya sea si se sale de esta sección por una excepción (terminación anómala) o después de pasar por ella (terminación normal).

El control llega a una instrucción __try mediante la ejecución secuencial simple (paso explícito). Cuando el control entra en __try, su controlador asociado se activa. Si el flujo de control alcanza el final del bloque try, la ejecución continúa del modo siguiente:

  1. Se invoca al controlador de terminación.

  2. Cuando el controlador de terminación finaliza, la ejecución continúa después de la instrucción __finally. Sin embargo, la sección protegida (por ejemplo, mediante una instrucción goto fuera del cuerpo protegido o una instrucción return), el controlador de finalización se ejecuta antes de que el flujo de control salga de la sección protegida.

    Una instrucción __finally no bloquea la búsqueda de un controlador de excepciones adecuado.

Si se produce una excepción en el __try bloque , el sistema operativo debe encontrar un controlador para la excepción o se producirá un error en el programa. Si se encuentra el controlador, se ejecutan todos y cada uno de los bloques __finally y la ejecución se reanuda en el controlador.

Por ejemplo, suponga que una serie de llamadas de función vincula la función A a la función D, como se muestra en la ilustración siguiente. Cada función tiene un controlador de finalización. Si se produce una excepción en la función D y se controla en A, se llama a los controladores de finalización en este orden mientras el sistema desenreda la pila: D, C, B.

Diagram of the order of termination handler execution.

El diagrama comienza con la función A, que llama a la función B, que llama a la función C, que llama a la función D. La función D genera una excepción. A continuación, se llama a los controladores de terminación en este orden: controlador de terminación D, luego C, B y, a continuación, A controla la excepción.

Orden de ejecución del controlador de terminación

Nota:

El comportamiento de try-finally es diferente del de otros lenguajes que admiten el uso de finally, como C#. Una instrucción __try puede tener __finally o __except, pero no ambos. Si se van a usar ambos conjuntamente, una instrucción try-except externa debe incluir la instrucción try-finally interna. Las reglas que especifican cuándo se ejecuta cada bloque también son diferentes.

A efectos de compatibilidad con versiones anteriores, _try, _finally y _leave son sinónimos de __try, __finally y __leave, a menos que se especifique la opción del compilador/Za (deshabilitar extensiones de lenguaje).

La palabra clave __leave

La palabra clave __leave solo es válida dentro de la sección protegida de una instrucción try-finally y su efecto es saltar al final de la sección protegida. La ejecución continúa en la primera instrucción del controlador de finalización.

Una instrucción goto también puede saltar fuera de la sección protegida, pero el rendimiento se degrada porque invoca el desenredado de la pila. La instrucción __leave es más eficaz porque no produce el desenredado de la pila.

Finalización anómala

La salida de una instrucción try-finally mediante el uso de la función en tiempo de ejecución longjmp se considera una finalización anómala. No es válido saltar dentro de una instrucción __try , pero sí fuera. Todas las instrucciones __finally que están activas entre el punto de salida (finalización normal del bloque __try) y el punto de destino (el bloque __except que controla la excepción) deben ejecutarse. Esto recibe el nombre de desenredado local.

Si un bloque __try se finaliza de forma prematura por cualquier motivo, incluido un salto fuera del bloque, el sistema ejecuta el bloque __finally asociado como parte del proceso de desenredado de la pila. En tales casos, la función AbnormalTermination devuelve true si se llama desde el bloque __finally, de lo contrario, devuelve false.

No se llama al controlador de finalización si un proceso se elimina en medio de la ejecución de una instrucción try-finally.

FIN de Específicos de Microsoft

Consulte también

Escritura de un controlador de terminación
Structured Exception Handling (C/C++)
Palabras clave
Sintaxis del controlador de terminación