17

我正在用 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)条款)

使用 MSVC for x86 编译此代码时(我使用的是 2010),结果如预期:

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

以此类推,无限循环。

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

Throwing
Catch 2
Done

异常完全跳过了内部的 catch 子句!

这只发生if (1 ==0)在我的代码中存在该子句时。当我删除它时,异常会按预期在“Catch 1”中捕获。

我试过使用其他编译器:

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

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

谢谢。

4

3 回答 3

1

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

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

Visual Studio 帮助还包含一条语句(在“优化最佳实践”下),不鼓励 64 位代码中的 try/catch 块。

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

if (1==0) {
//continue;
}
于 2013-10-31T14:03:47.083 回答
0

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

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

于 2013-11-01T11:17:55.650 回答
0

试试 switch /FAs 开关:

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

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

然后,在两个输出之间进行差异。在这里发布差异。我相信有些人会告诉你原因和方式,也许还有一些编译器设置或代码解决方法。

于 2013-10-25T13:39:23.760 回答