Estaba aprendiendo el ejemplo y no soy un

#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION

#include <excpt.h>

int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {

    puts("in filter.");

    if (code == EXCEPTION_ACCESS_VIOLATION) {

        puts("caught AV as expected.");

        return EXCEPTION_EXECUTE_HANDLER;

    }

    else {

        puts("didn't catch AV, unexpected.");

        return EXCEPTION_CONTINUE_SEARCH;

    };

}

int main()

{

    int* p = 0x00000000;   // pointer to NULL

    puts("hello");

    __try {

        puts("in try");

        __try {

            puts("in try");

            *p = 13;    // causes an access violation exception;

        }
        __finally {

            puts("in finally. termination: ");

            puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");

        }

    }
    __except (filter(GetExceptionCode(), GetExceptionInformation())) {

        puts("in except");

    }

    puts("world");

}

La salida del programa es:

hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
        abnormal
in except
world

Estoy confundido sobre por qué va a filtrar primero y luego a finalmente y luego imprime "en excepto". ¿No es cierto si va a __ excepto que debería completar la ejecución?

-5
Sumit Lubal 25 ago. 2016 a las 09:17

2 respuestas

La mejor respuesta

Esas no son excepciones estándar de C ++, sino extensiones de lenguaje propias de Microsoft.

Si hubiera continuado desde la página donde encontró ese ejemplo, lea la documentación de { {X0}}, habrías encontrado esto:

Si se encuentra un controlador, todos y cada uno de los bloques __finally se ejecutan y la ejecución se reanuda en el controlador.

Esto no es sorprendente: en los lenguajes que tienen estas construcciones, el bloque finally siempre se ejecuta (ese es el propósito).
Es solo que normalmente, el programador no tiene control en tiempo de ejecución sobre dónde o si se detecta la excepción, por lo que no puede interrumpir el procesamiento para mirar detrás de escena como lo hizo con filter.

1
molbdnilo 25 ago. 2016 a las 07:01

En el sitio de microsoft se escribe la siguiente declaración:

Salir de una instrucción try-finalmente utilizando la función de tiempo de ejecución longjmp se considera una terminación anormal. Es ilegal saltar a una declaración __try, pero es legal saltar de una. Todas las sentencias __finally que están activas entre el punto de partida (terminación normal del bloque __try) y el destino (el bloque __except que maneja la excepción) deben ejecutarse. Esto se llama relajación local.

Se menciona claramente que el primer bloque try se ejecuta, luego _except y finalmente, antes de salir del bloque try, se ejecuta finalmente el bloque.

Referir. https://msdn.microsoft.com/en-us/library/9xtt5hxz.aspx

0
Hardipsinh Jadeja 25 ago. 2016 a las 06:32