有人能解释一下CFC异常和MFC中的结构化异常之间的区别吗?
答案 0 :(得分:21)
你实际上有三种机制:
try
/ catch
)__try
/ __except
)TRY
,CATCH
- 建立在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 ++语言的try
,catch
和throw
关键字,就可以获得此效果。
SEH异常具有比C ++异常更多的功能,如支持恢复,以及所谓的“向量”处理程序(接收异常通知,但不一定防止堆栈展开),但除非您明确知道要使用他们,我会避免他们。可能最常见的用途是使用MiniDumpWriteDump编写崩溃转储,如果您的程序执行非法或未定义的操作。
答案 4 :(得分:1)
C ++异常将跨平台工作。不幸的是,SEH会严重限制可移植性(除了可能跨越不同的Windows版本)。
此外,SEH似乎捕获了许多本机Windows异常(例如访问冲突,指定了无效句柄)等。