危险错误Visual c ++ 2005

use*_*027 8 c++ visual-c++ compiler-bug visual-c++-2005

我使用Visual Studio 2005运行C++ Win32控制台应用程序时遇到了非常严重的错误.使用以下项目属性运行下面的代码(简化)时会出现问题:C++ | optimization | optimization |/O2(或/ O1,或/ Ox),C++ | optimization |整个程序优化|/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;
    }
Run Code Online (Sandbox Code Playgroud)

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

us2*_*012 3

你可以显着减少你的例子,但仍然遇到同样的问题!您不需要两个实例,也不需要任何其他局部变量或成员变量。另外,您可以硬编码MAXVAL.

快速总结“解决”问题的内容:

  • 制作MAXVAL一个非常数int
  • 设置setupVal2为小于 10 的值
  • 令人惊讶的是,将条件更改10<valval>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;
}
Run Code Online (Sandbox Code Playgroud)

正如反汇编所证明的,问题在于编译器认为10<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   : }
Run Code Online (Sandbox Code Playgroud)

  • 所以这个问题是可以重现的。我认为这会产生深远的影响;许多使用 Visual C++ 2005 编译的 C++ win32 控制台应用程序(使用上述设置,这是标准的)的行为和输出是未定义的!我不再信任这个编译器了。 (2认同)
  • [此处](https://connect.microsoft.com/VisualStudio/feedback/details/801924/compiler-bug-visual-studio-2005-professional#details) 向 Microsoft 提交了错误报告 (2认同)