C++ MSVC x64 中尝试捕获子句"Skips"例外

C++ Exception "Skips" Try-Catch Clause in MSVC x64

本文关键字:子句 Skips 例外 MSVC x64 C++      更新时间:2023-10-16

我正在用C++编写一个程序。该程序在Win32(x86)上运行良好,最近我尝试为x64本机编译它。当然,这些东西并没有马上起作用。

调试问题后,我设法用这个简单的代码片段重现它:

class MyException { };
int main()
{
    try {
        for (;;) {
            try {
                std::cout << "Throwing" << std::endl;
                throw MyException();
                if (1 == 0) {
                    continue;
                }
            } catch (const MyException&) {
                std::cout << "Catch 1" << std::endl;
            }
        }
    } catch (const MyException&) {
        std::cout << "Catch 2" << std::endl;
    }
    std::cout << "Done" << std::endl;
    return 0;
}

(我很快就会解释if (1==0)条款)

使用 x86 的 MSVC 编译此代码时(我使用了 2010),结果符合预期:

Throwing
Catch 1
Throwing
Catch 1
Throwing
Catch 1
Throwing
Catch 1
...

依此类推,在一个无限循环中。

但是,为 x64 编译此代码会导致:

Throwing
Catch 2
Done

该例外完全跳过了内部捕获子句!

仅当 if (1 ==0) 子句存在于我的代码中时,才会发生这种情况。当我删除它时,异常按预期在"Catch 1"中捕获。

我尝试使用其他编译器:

  • 此错误也发生在VS 2012中。
  • MinGW和MinGW-w64按预期工作。

我的问题:这是一个 MSVC 错误,还是我丢失C++中的一些未定义的行为?如果这确实是MSVC错误,我很想听听有关原因的一些见解。

谢谢。

此错误可能与编译器优化有关 - 有趣的是,链接器在发布版本中崩溃(理论上会打开完全优化)。

您的调试版本是否完全禁用了优化 (/Od)?

Visual Studio 帮助还包含一个语句(在"优化最佳做法"下),不鼓励 64 位代码中的 try/catch 块。

如果在发布版本中关闭优化,链接器不会崩溃。 如果您只删除"继续"语句,它也不会崩溃(但会重现不良行为)。

if (1==0) {
//continue;
}

尝试切换/FAs 开关:

http://msdn.microsoft.com/en-us/library/367y26c6%28v=vs.80%29.ASPX

在"编译器设置"的"附加输出文件"中的某个位置。(确保所有其他设置相同)

然后,在两个输出之间做一个差异。 在此处发布差异。我相信有些人会告诉你为什么和如何,也许还有一些编译器设置或代码解决方法。

这是一个

古老的已知问题,在挖掘出来之后,这就是我们前段时间发现的。

http://social.msdn.microsoft.com/Forums/en-US/19eb8218-0dc4-4e4f-954f-4c4c3b3cd118/why-am-i-not-being-alerted-of-exceptions-from-methods-that-are-run-when-the-application-loads?forum=csharpide