Опасная ошибка Visual c ++ 2005

Я столкнулся с очень серьезной ошибкой, используя 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 Professional (версия 8.0.50727.867), ОС Windows 7.
Мои вопросы: может ли кто-нибудь попытаться воспроизвести эту ошибку с помощью Visual Studio 2005 (я уже пробовал VS 2010, нет проблем), и если да, что здесь происходит?
Могу ли я предположить, что более новые версии решили эту проблему (я рассматриваю покупку VS 2012)
Спасибо

8

Решение

Вы можете уменьшить свой пример существенно и до сих пор та же проблема! Вам не нужны два экземпляра, и вам не нужны никакие другие локальные переменные или переменные-члены. Кроме того, вы можете жестко MAXVAL,

Краткое изложение того, что «решает» проблему:

  • изготовление MAXVAL неконстантность int
  • установка setupVal2 до значения менее 10
  • удивительно, меняя условия 10<val в val>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<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   : }
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]