为啥 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?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL表名和数据库关键字相同解决办法

请问vc中为啥有的函数前缀为下划线,有的函数无下划线?两者有啥区别?

Visual Studio 2008 内联汇编 关键字__asm出错

“警告 C4987:使用了非标准扩展:'throw (...)'”是啥意思?

为啥同样的C程序在VC++6.0可以运行,在VS2010就不可以?

gcc悄无声色将静态函数内联了