我想知道捕获我抛出的异常哪种方式更好:是使用__try / __except块还是try / catch块?
我正在使用C++编写程序,并且该程序只在Windows上使用,因此可移植性不是问题。
谢谢!
我正在使用C++编写程序,并且该程序只在Windows上使用,因此可移植性不是问题。
谢谢!
它们是两个非常不同的东西。try/catch
是您所熟悉的 C++ 关键字。而 __try/__except
则用于捕获系统异常,例如除零或访问无效等 Windows 自身引发的异常。有关此功能的详细描述,请参阅MSDN Library文章。
您还可以利用 Windows SEH 功能来捕获 C++ 异常,但无法从中获取抛出的异常对象,因此在实际处理异常时上下文信息将为零,这是不可取的。最好的方法是永远不要捕获 SEH 异常,因为它们总是令人讨厌的。如果确实需要将它们结合起来,则可以使用 _set_se_translator() 将 SEH 异常转换为 C++ 异常。
try
/catch
块。__try
/ __except
是用于捕获SEH(Windows生成的错误),而不是用于捕获通用异常。__try
和__catch
在抛出异常时可能无法运行C++解构函数或正确解开堆栈。/EHa
的文档在这里发生了误导,或者至少是不完整的。 如果有人找到确凿的文档证明这是错误的,我会很高兴删除这个答案。try
和catch
,因为它们是标准的,而__try
和__except
则不是。__try/__except
是为调用不支持异常但使用结构化错误代码/处理机制的Win32 C代码而设计的。 __try/__except
将把C错误转换为类似于C++ try/catch 的异常块。
更多信息,请参见此MSDN文章。
标准的C++使用try/catch块,因此如果您需要基于标准C++库的“标准”异常机制,则建议使用它们。
但是,如果您计划使用Windows SDK提供的结构化异常处理(参见这里),则请使用__try
/__except
。
std::exception
不是 STL 类。 - Billy ONeal一旦你抛出了某个东西,你就没有太多的选择来捕获它。如果你抛出C++异常(即使用throw
),那么请使用try
/catch
。如果你抛出Windows异常(即使用RaiseException
),那么请使用__try
/__except
。试图混合它们只会给你的生活增加不必要的麻烦。
RaiseException
抛出它,所以必须使用__except
来捕获它。 - Rob Kennedy
__try
和__except
严格来说是基于C的API/ABI。 - Billy ONeal/EHa
仅仅允许C++异常处理结构(当你使用try
和catch
时)捕捉SEH异常,但是当使用__try
和__except
时,C++堆栈仍然无法正确地展开。 - Billy ONeal__except
可以捕获 C++ 异常;但我的理解是,在这样做时,它不能保证提供 C++ 栈展开语义。除非像 Hans 所说的那样,在/EHa
下。 (请不要使用/EHa
) - Billy ONeal