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
}
// . . .
Gramática
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:
Se invoca al controlador de terminación.
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óngoto
fuera del cuerpo protegido o una instrucciónreturn
), 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 bloque __try
, el sistema operativo debe buscar un controlador para la excepción; de lo contrario, el programa producirá un error. 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.
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 finalizació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 finalizació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
Escribir un controlador de finalización
Structured Exception Handling (C/C++)
Palabras clave
Sintaxis del controlador de terminación