为啥 VC++ 引入了非标准关键字:__leave?
Posted
技术标签:
【中文标题】为啥 VC++ 引入了非标准关键字:__leave?【英文标题】:Why does VC++ introduce the nonstandard keyword: __leave?为什么 VC++ 引入了非标准关键字:__leave? 【发布时间】:2013-09-16 01:20:30 【问题描述】:根据MSDN:
__leave 语句效率更高,因为它不会导致 堆栈展开。
据我理解,就是说:“这么普通的代码sn-p是危险的!”
struct A
int* p;
A() : p(new int)
~A() delete p;
;
void f()
__try
A a;
... // Doing somthing
if (the thing has gone bad) __leave;
... // Continue
__finally
在 C++ 项目中完全避免 __leave 是最佳做法吗?
【问题讨论】:
实际上,我认为使用 ISO C++ 标准之外的 anything 可能 是邪恶的 - 它使移植更加困难。在您的特定情况下,这可能不是问题,但有些人重视它。__try
, __except
, __leave
和 __finally
用于结构化异常处理,这是一种特定于 Windows 的功能,具有非常特殊的用途(例如,捕获堆栈保护页面异常、访问冲突和公司);对于“常规”C++,你不需要它们。
关键是抱怨__try
... __except
就像抱怨CreateWindow
不可移植——当然不是,它旨在处理非常特定于操作系统的东西首先,甚至 Microsoft 都告诉您避免在 C++ 中使用 __try
,除非您确实需要使用 SEH。 SEH 不是标准中已有内容的非标准替代品,它用于标准准确避免谈论的内容,因为它不能以与平台无关的方式处理。跨度>
@DietrichEpp 我不明白关于“支持标准库”的部分。除了标准语言之外,标准库不需要任何支持。
@EJP:它在 CRT 内部被广泛使用(在 CRT 源代码上的快速grep -r __try | wc -l
显示了__try
的 171 个实例)来处理特定于 Windows 的内容并构建我们漂亮的 C/C++ 库对其进行抽象。可以只使用 SEH Windows 函数来完成吗?当然,但由于__try
已经存在(在处理上述场景以及驱动程序编程时,它对 VC++ 用户非常有用)并且比替代方案更方便,所以他们使用了它。同样,我同意你的观点,它对于 CRT 不是必需的,但它实际上 用于支持它。
【参考方案1】:
http://msdn.microsoft.com/en-us/library/yb3kz605.aspx
说:
对于 C++ 程序,应使用 C++ 异常处理而不是结构化异常处理。有关详细信息,请参阅 C++ 语言参考中的异常处理。
编辑: 此外,最好避免使用编译器特定的功能。
【讨论】:
另外:虽然 Windows 和 Visual C++ 支持结构化异常处理 (SEH),但我们建议您使用 ISO 标准 C++ 异常处理,因为它使代码更便携和灵活。尽管如此,在现有代码或特定类型的程序中,您仍可能必须使用 SEH。 (msdn.microsoft.com/en-us/library/swezty51.aspx)【参考方案2】:这取决于。 __try
/__finally
是为 Win32 结构化异常处理而构建的,这与 C++ 结构化异常处理完全相同。如果您正在编写 Win32 驱动程序,您必须使用 Win32 SEH。如果没有,我会坚持使用 C++ EH。
【讨论】:
以上是关于为啥 VC++ 引入了非标准关键字:__leave?的主要内容,如果未能解决你的问题,请参考以下文章
请问vc中为啥有的函数前缀为下划线,有的函数无下划线?两者有啥区别?
Visual Studio 2008 内联汇编 关键字__asm出错
“警告 C4987:使用了非标准扩展:'throw (...)'”是啥意思?