Ответ 1
Кажется, это может быть эта ошибка? Где возникает проблема при возврате значений с плавающей запятой, сгенерированных аналогичным образом?
Используя VS2012, я заметил, что switch
, работающий уже несколько лет, кажется, сломан в сборках Release, но работает корректно (или, по крайней мере, так, как было) в сборке Debug. Я не вижу ничего плохого в коде, поэтому я бы по достоинству оценил правильность использования инструкций return
из блока switch
.
Следующий код компилируется нормально, но дает неправильный вывод в сборке Release на 32-битном Win7...
#include <stdio.h>
#include <tchar.h>
class CSomeClass
{
public:
float GetFloat(int nInt)
{
printf("GetFloat() - entered\n");
switch (nInt)
{
case 1 :
printf("GetFloat() - case 1 entered\n");
return 0.5F;
case 0 :
printf("GetFloat() - case 0 entered\n");
return 1.0F;
case 2 :
printf("GetFloat() - case 2 entered\n");
return 2.0F;
case 3 :
printf("GetFloat() - case 3 entered\n");
return 3.0F;
case 4 :
printf("GetFloat() - case 4 entered\n");
return 4.0F;
}
printf("GetFloat() - exit\n");
return 1.0F;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CSomeClass pClass;
float fValue = pClass.GetFloat(3);
printf("fValue = %f\n", fValue);
return 0;
}
Если вы можете повторить проблему и иметь учетную запись MS Connect, возможно, вы тоже можете проголосовать за нее?
Фактические результаты
Релиз сборки дает следующий неверный результат:
GetFloat() - entered
GetFloat() - case 3 entered
fValue = 0.000000
Ожидаемые результаты
Сборка отладки дает следующий правильный результат:
GetFloat() - entered
GetFloat() - case 3 entered
fValue = 3.000000
Кажется, это может быть эта ошибка? Где возникает проблема при возврате значений с плавающей запятой, сгенерированных аналогичным образом?
Определенно ошибка компилятора. Здесь выполняется снятый код asm (удаляются прыжки и т.д.). Компилятор удаляет некоторый код, который, по его мнению, не нужен, даже если это не так.
Вывод сборки:
// inside GetFloat
00E0104D fld dword ptr ds:[0E021D8h] // load constant float onto FPU stack
00E01068 add esp,4
00E0106B ret
// back in main
00E01098 cvtss2sd xmm0,xmm0 // convert float to double. assumes the returned value to be in xmm0
00E0109C sub esp,8
00E0109F movsd mmword ptr [esp],xmm0 // push double being printed (xmm0 is with high likelyhood = 0)
00E010A4 push 0E021B8h // push output string
00E010A9 call dword ptr ds:[0E02090h] // call printf
Отладка сборки:
003314B0 fld dword ptr ds:[335964h] // load const float onto FPU stack
[...]
00331500 mov esp,ebp
00331502 pop ebp
00331503 ret 4
// back in main
00331598 fstp dword ptr [fValue] // copies topmost element of the FPU stack to [fValue]
0033159B cvtss2sd xmm0,dword ptr [fValue] // correctly takes returned value (now inside [fValue] for conversion to double
003315A0 mov esi,esp
003315A2 sub esp,8
003315A5 movsd mmword ptr [esp],xmm0 // push double being printed
003315AA push 335940h // push output string
003315AF call dword ptr ds:[3392C8h] // call printf
Сбор данных из всех результатов, скорее всего, это ошибка компилятора.
/O1
работает правильноDebug
работает правильноcout
, так и printf
И, наверное, самое главное - это 100% стандартов. Поэтому он должен работать.