C ++异常和结构化异常之间的区别

时间:2010-09-24 11:35:13

标签: c++ exception mfc

有人能解释一下CFC异常和MFC中的结构化异常之间的区别吗?

5 个答案:

答案 0 :(得分:21)

你实际上有三种机制:

  • C ++异常,由编译器(try / catch
  • 实现
  • Windows提供的结构化异常处理(SEH)(__try / __except
  • MFC异常宏(TRYCATCH - 建立在SEH / C ++异常之上 - 另见TheUndeadFish的评论)

C ++异常通常保证在堆栈展开期间自动清理(即运行本地对象的析构函数),其他机制则不行。

C ++异常仅在显式抛出时才会发生。许多操作可能会出现结构化异常,例如:由于未定义的行为,将无效指针传递给API,卸载内存映射文件的后备存储等等。

MFC确实引入了异常宏来支持异常,即使编译器没有实现它们也是如此。

答案 1 :(得分:10)

这是一个繁重的实现细节,但在Windows上,C ++异常也是SEH异常。异常代码是0xE04D5343(最后三个字节='MSC')。并且所有常规SEH支持都用于展开堆栈,运行自动清理代码并过滤异常,以便选择正确的catch子句。在过滤器表达式中获取抛出的异常对象是由CRT添加的管道,超出了SEH提供的范围。 SEH还支持__finally子句,但不会在标准C ++中使用。

进一步的实现细节是/ EH编译器设置。默认(/ EHsc)允许编译器优化生成的代码并抑制运行自动清理所需的异常过滤器。如果它可以看到所发出的C ++代码都不会引发异常。这首先是空间优化,x86代码的小时间优化,但不适用于x64代码。要获得SEH异常的自动清理,您必须使用/ EHa进行编译,以便抑制此优化。

将C ++异常与SEH结合的好策略是使用_set_se_translator(),以便将SEH异常转换为C ++异常。虽然抓住SEH例外通常并不明智,但它们几乎总是令人讨厌。

答案 2 :(得分:7)

C ++异常是编程语言C ++的一个特性。 结构化异常是Windows操作系统的不同概念。 这两个使用类似的语法,但在技术上是不同的。 Windows结构化异常不仅可用于C ++,还可用于例如与C.

有时是统一处理两者的解决方案:在Windows应用程序中,您可以提供处理程序函数,该函数捕获所有结构化异常并抛出C ++异常(由您定义)。

答案 3 :(得分:5)

两者都提供了发生错误时堆栈展开的机制。

结构化异常由Windows提供,并得到内核的支持。如果您执行访问无效内存位置等操作,则会由Windows引发它们。它们还用于支持自动堆栈增长等功能。它们很少被自己使用,但C ++,.NET和类似语言中的语言异常通常建立在它们之上。您可以使用__try__catch等特殊关键字来处理这些例外情况。但是,处理它们相对困难且容易出错,因为您可以破坏自动堆栈扩展等功能,并可能破坏C ++语言异常。

C ++异常由C ++语言指定。抛出和捕获的数据类型是C ++对象(包括基本类型的可能性)。编译器和运行时在底层结构化异常机制之上实现这些。如果您使用C ++语言的trycatchthrow关键字,就可以获得此效果。

SEH异常具有比C ++异常更多的功能,如支持恢复,以及所谓的“向量”处理程序(接收异常通知,但不一定防止堆栈展开),但除非您明确知道要使用他们,我会避免他们。可能最常见的用途是使用MiniDumpWriteDump编写崩溃转储,如果您的程序执行非法或未定义的操作。

答案 4 :(得分:1)

C ++异常将跨平台工作。不幸的是,SEH会严重限制可移植性(除了可能跨越不同的Windows版本)。

此外,SEH似乎捕获了许多本机Windows异常(例如访问冲突,指定了无效句柄)等。