尝试catch在C ++中表现得很糟糕

时间:2016-08-25 06:17:09

标签: c++ winapi exception

我正在学习这个例子而我不是

merge into employeegrades eg
using (select id, name from temp_emp)  emp
on (eg.id = emp.id)
when matched and eg.grades > 150 then
delete 
when matched
update set eg.grades = eg.grades+25
when not matched then
insert (id,grades)
values (emp.id, 25);

计划的输出是:

#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");

}

我很困惑为什么它首先过滤然后最后过滤然后打印“in except”。 如果它转到__则不是真的,那么它应该完成执行。

2 个答案:

答案 0 :(得分:1)

这些不是标准的C ++异常,而是微软自己的语言扩展。

如果您从找到该示例的页面继续阅读the documentation for try-finally,您会发现:

  

如果找到处理程序,则执行任何和所有__finally块,并在处理程序中继续执行。

这并不奇怪 - 在具有这些结构的语言中,finally块总是被执行(这就是它的目的)。
通常情况下,程序员没有运行时控制异常被捕获的位置,因此您不能像处理filter那样中断处理以查看幕后。

答案 1 :(得分:0)

在micorosoft网站上写下如下声明:

  

使用longjmp运行时函数退出try-finally语句被视为异常终止。跳入__try语句是违法的,但跳出一个是合法的。必须运行在出发点(__try块的正常终止)和目标(处理异常的__except块)之间有效的所有__finally语句。这称为本地展开。

它清楚地提到第一个try块然后执行_except然后在退出try块之前最后执行finally块。

参考。 https://msdn.microsoft.com/en-us/library/9xtt5hxz.aspx