C ++,__try和try / catch / finally

我想知道一些关于C ++ try / catch / finally块。 我已经看到这些命令有两个下划线像__try。 但MVSC 2010项目也运行没有下划线。 那么你什么时候需要这些下划线?

在Windows上,操作系统级别支持exception。 被称为结构化exception处理(SEH),它们大致相当于Unix信号。 为Windows生成代码的编译器通常利用这一点,他们使用SEH基础结构来实现C ++exception。

为了与C ++标准保持一致, throwcatch关键字只抛出和捕获C ++exception。 MSVC编译器相应的SEHexception代码是0xe06d7343。 最后3个字节是“msc”的ASCII码。

将它与操作系统支持统一也意味着C ++析构函数将在堆栈展开期间调用SEHexception。 展开的代码在Windows内部,并且像SEH一样对待SEH所抛出的SEH。 但是,Microsoft编译器有一个优化,试图避免生成所需的代码,以确保在所有情况下调用析构函数。 如果它可以certificate在控制对象的生命周期的范围块内没有throw语句,则跳过注册码。 这与asynchronousSEHexception不兼容,如果您打算捕获SEHexception,则应使用/ EHa编译选项来抑制此优化。

有很多SEHexceptiontypes。 可以由操作系统生成的列在ntstatus.h SDK头文件中。 另外,你可能会使用SEH来实现自己的exception处理的代码,他们将使用自己的exception代码。 与.NET一样,托pipe的exception使用0xe0434f4d(“com”)exception代码。

要在C ++程序中捕获SEHexception,您必须使用非标准的__try关键字。 __except关键字类似于C ++ catch关键字。 它具有更多的function,您可以指定一个exceptionfilterexpression式来确定是否应该捕获一个活动的exception。 任何事情都是可能的,但是您通常只查看传递的exception信息,看看您是否有兴趣处理它。 __finally关键字可让您编写处理exception后运行的代码。 在C ++中没有相同之处,但在其他语言中并不罕见。

正如评论中指出的那样,所有这些都是相当差的文件。 certificate是在布丁。 这里有一个你可以玩的例子程序。 它演示了SEHexception如何仍然允许调用C ++析构函数,只要使用/ EHa进行编译以及如何在SEH之上实现C ++exception。 需要MSVC编译器,使用Ctrl + F5运行以避免debugging器有帮助:

 #include "stdafx.h" #include <windows.h> #include <iostream> // NOTE: the value of the C/C++, Code Generation, Enable C++ Exceptions setting in important // Try it both with /EHsc (the default) and /EHa to see the difference class Example { public: ~Example() { std::cout << "destructed" << std::endl; } }; int filterException(int code, PEXCEPTION_POINTERS ex) { std::cout << "Filtering " << std::hex << code << std::endl; return EXCEPTION_EXECUTE_HANDLER; } void testProcessorFault() { Example e; int* p = 0; *p = 42; } void testCppException() { Example e; throw 42; } int main() { __try { testProcessorFault(); } __except(filterException(GetExceptionCode(), GetExceptionInformation())) { std::cout << "caught" << std::endl; } __try { testCppException(); } __except(filterException(GetExceptionCode(), GetExceptionInformation())) { std::cout << "caught" << std::endl; } return 0; } 

输出:

 Filtering c0000005 destructed caught Filtering e06d7363 destructed caught 

__try / __except用于捕获SEH(Windows生成的错误),不用于捕获一般exception。

try / catch是C ++标准为处理一般C ++exception而规定的。

对于你写的标准C ++代码,你应该总是使用try / catch而不是__try / __except

此外, finally不是C ++标准指定的结构,它适用于你,因为它是一个微软的编译器扩展

__try/__except 微软的特定之外如果你希望你的代码能够与其他编译器(例如c ++)(或者)在另一个操作系统上编译,避免使用它们,并且坚持使用标准的try/catch语句