我想知道有关C++ try/catch/finally块的信息。我看过这些命令带有两个下划线,例如__try。但是MVSC 2010项目也没有下划线。那么什么时候需要这些下划线?
最佳答案
在Windows上,操作系统级别支持异常(exception)。它们被称为结构化异常处理(SEH),与Unix信号大致相同。为Windows生成代码的编译器通常会利用此优势,它们使用SEH基础结构来实现C++异常。
与C++标准保持一致,throw和catch关键字仅会抛出C++异常。 MSVC编译器的相应SEH异常代码为0xe06d7363。最后3个字节是“msc”的ASCII码。
通过操作系统支持将其统一还意味着,在针对SEH异常的堆栈展开期间将调用C++析构函数。执行展开的代码在Windows内部,并且将引发的SEH与任何SEH完全相同地对待。但是,Microsoft编译器进行了优化,试图避免生成所需的代码,以确保在所有情况下都调用析构函数。如果可以证明在作用域块中没有控制对象生存期的throw语句,那么它将跳过注册代码。这与异步SEH异常不兼容,如果您打算捕获SEH异常,则应使用/EHa编译选项来抑制此优化。
SEH异常类型很多。 ntstatus.h SDK头文件中列出了可由操作系统生成的文件。另外,您可能会与使用SEH来实现自己的异常处理的代码互操作,他们将使用自己的异常代码。与.NET一样,托管异常也使用0xe0434f4d(“com”)异常代码。
要在C++程序中捕获SEH异常,必须使用非标准的__try关键字。 __except关键字类似于C++ catch关键字。它具有更多功能,您可以指定一个异常过滤器表达式,该表达式确定是否应捕获 Activity 异常。一切皆有可能,但是您通常只查看传递的异常信息,以查看是否有兴趣处理它。 __finally关键字使您可以编写在处理异常之后运行的代码。在C++中没有等效项,但在其他语言中并不罕见。
正如评论中指出的那样,所有这些文献的记录都很少。证明在布丁里。这是您可以使用的示例程序。它演示了SEH异常如何仍允许调用C++析构函数,前提是您使用/EHa进行编译以及如何在SEH之上实现C++异常。需要MSVC编译器,并使用Ctrl + F5运行,以避免调试器有用:
#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
关于c++ - C++,__ try和try/catch/finally,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7049502/