【问题标题】:Dangerous error Visual c++ 2005危险错误 Visual c++ 2005
【发布时间】:2013-09-18 11:34:22
【问题描述】:

我在使用 Visual Studio 2005 运行 C++ Win32 控制台应用程序时遇到了一个非常严重的错误。使用以下项目属性运行以下代码(简化)时,将显示该问题:C++|优化|优化|/O2(或/O1,或/Ox),C++|优化|整个程序优化|/GL,链接器|优化|/ltcg

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    const int MAXVAL=10;
    class MyClass
    {
    private:
      int p;
      bool isGood;
    public:
      int SetUp(int val);
    };
    int MyClass::SetUp(int val)
    {
      isGood = true;
      if (MAXVAL<val)
      {
        int wait;
        cerr<<"ERROR, "<<MAXVAL<<"<"<<val<<endl;
        cin>>wait;
        //exit(1);      //for x64 uncomment, for win32 leave commented
      }
      if (isGood) p=4;
      return 1;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
      int wait=0, setupVal1=10, setupVal2=12;
      MyClass classInstance1;
      MyClass classInstance2;
      if (MAXVAL>=setupVal1) classInstance1.SetUp(setupVal1);
      if (MAXVAL>setupVal2) classInstance2.SetUp(setupVal2);
      cerr<<"exit, enter value to terminate\n";
      cin>>wait;
      return 0;
    }

输出显示值 10 小于值 10!我已经发现将设置 /O2 更改为 /Od 可以解决问题(设置 /Og,它是 /O2 的一部分,会导致问题),但这确实会减慢执行时间。稍微改变一下代码也可以解决它,但是嘿,我永远不能确定代码是可靠的。我正在使用 Visual Studio 2005 专业版(版本 8.0.50727.867),操作系统 Windows 7。 我的问题是:有人可以尝试使用 Visual Studio 2005 重现此错误(我已经尝试过 VS 2010,没问题),如果是这样,这里会发生什么? 我可以假设较新的版本已经解决了这个问题(我考虑购买 VS 2012) 谢谢

【问题讨论】:

  • 现在还支持VS2005吗?它已经 8 岁了。
  • 在我的VS2005上试了一下,确实输出是ERROR, 10&lt;10
  • 您是否考虑过下载 Visual Studio 的快速版本?每个发布年份包含的编译器都相同
  • Express 版本不包含 openMP

标签: c++ visual-c++ visual-c++-2005 compiler-bug


【解决方案1】:

您可以显着减少您的示例,但仍然会遇到同样的问题!您不需要两个实例,也不需要任何其他本地或成员变量。此外,您可以硬编码MAXVAL

快速总结“解决”问题的方法:

  • 使MAXVAL 成为非常量int
  • setupVal2 设置为小于 10 的值
  • 令人惊讶的是,将条件10&lt;val 更改为val&gt;10 !!!

这是我重现问题的最小版本:

#include "stdafx.h"
#include <iostream>
using namespace std;

class MyClass
{
public:
    int SetUp(int val);
};

int MyClass::SetUp(int val)
{
    if (10<val)
        cout<<10<<"<"<<val<<endl;
    return 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
    int setupVal1=10, setupVal2=12;
    MyClass classInstance;

    classInstance.SetUp(setupVal1);
    classInstance.SetUp(setupVal2);

    cin.get();
    return 0;
}

反汇编证明的问题是编译器认为10&lt;val 始终为真,因此省略了检查。

_TEXT   SEGMENT
?SetUp@MyClass@@QAEHH@Z PROC                ; MyClass::SetUp
; _val$ = ecx

; 16   :    if (10<val)
; 17   :        cout<<10<<"<"<<val<<endl;

    mov eax, DWORD PTR __imp_?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z
    push    eax
    push    ecx
    mov ecx, DWORD PTR __imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
    push    10                  ; 0000000aH
    call    DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z
    push    eax
    call    ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> >
    add esp, 4
    mov ecx, eax
    call    DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z
    mov ecx, eax
    call    DWORD PTR __imp_??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z

; 18   :    return 1;

    mov eax, 1

; 19   : }

【讨论】:

  • 所以问题是可重现的。我认为这会产生深远的影响;许多用 Visual C++ 2005 编译的 C++ win32 控制台应用程序的行为和输出(使用上述标准设置)是未定义的!!!我不再相信这个编译器了。
  • 很确定你不是第一个发现这个错误的人,但我在任何错误跟踪器上都找不到它......但我并没有太努力。
  • 您是否在 Microsoft Connect 上为此提交了错误报告?
  • @namezero 我没有 Connect 帐户(通常为 Linux 开发,但对这个问题感兴趣,因此安装了 VS2005 Express)。如果你有,你能把这个归档并在此处链接报告吗?将不胜感激。
  • 向微软提交错误报告here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
  • 1970-01-01
  • 2012-11-29
  • 1970-01-01
  • 2011-04-22
  • 2017-07-04
  • 2023-04-07
相关资源
最近更新 更多