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

Kri*_*nan 20 c++ mfc exception

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

pet*_*hen 21

你实际上有三种机制:

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

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

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

MFC确实引入了异常宏来支持异常,即使编译器没有实现它们.

  • Wile MFC 的异常过去使用不同的方法(我认为在 VC 支持 C++ 异常之前),MFC 的异常现在构建在 C++ 异常之上。实际上很有可能将 MFC 宏转换为 C++ try/catch,如下所述:http://msdn.microsoft.com/en-us/library/19z28s5c.aspx 所以在这一切之下,实际上只有 2不同的类型:C++ 异常和 SEH。 (3认同)
  • 不需要C++异常来保证清理.用/ EHa编译. (2认同)
  • @Hans - 嗯,真的吗?/EHa 与 /EHs 只影响 C++ 异常处理程序是否捕获结构化异常。我非常确定 C++ 标准*保证*清理 C++ 异常(保留此实现定义是没有意义的,因为必要的代码将根本不同)。 (2认同)

Han*_*ant 10

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

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

将SE ++与SEH结合使用的一个好策略是使用_set_se_translator(),这样就可以将SEH异常转换为C++异常.尽管捕获SEH异常通常并不明智,但它们几乎总是令人讨厌.


ur.*_*ur. 7

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

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


Dou*_*oug 5

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

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

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

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