25

使用 VS2012,我注意到switch已经工作了几年的 a 现在似乎在 Release 版本中被破坏了,但在 Debug 版本中可以正常工作(或至少像以前一样)。我看不出代码有什么问题,所以希望能得到一些关于在块return内使用语句的正确性的反馈。switch

以下代码编译正常,但在 Win7 32 位的 Release 版本中给出了错误的输出...

#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

MS Connect 错误报告

4

3 回答 3

7

听起来可能是这个错误?返回以类似方式生成的浮点值存在问题?

于 2013-02-12T15:34:54.233 回答
6

绝对是编译器错误。这是正在执行的精简 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
于 2013-02-12T15:44:46.140 回答
5

从所有结果中收集数据,这很可能是编译器错误。

  • x64 工作正常
  • /O1正常工作
  • 好吧,Debug工作正常
  • cout它在两者上都给出了相同的错误printf

而且,可能是最重要的 - 它 100% 符合标准。所以它应该工作。

于 2013-02-12T15:11:39.537 回答