Я столкнулся с очень серьезной ошибкой, используя 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)
Спасибо
Вы можете уменьшить свой пример существенно и до сих пор та же проблема! Вам не нужны два экземпляра, и вам не нужны никакие другие локальные переменные или переменные-члены. Кроме того, вы можете жестко MAXVAL
,
Краткое изложение того, что «решает» проблему:
MAXVAL
неконстантность int
setupVal2
до значения менее 1010<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 : }
Других решений пока нет …