Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it now wrong to "return" from a "switch" statement in C++11? [duplicate]

Tags:

Using VS2012, I noticed that a switch that's been working for several years now seems to be broken in Release builds but works correctly (or at least as it used to) in Debug builds. I can't see anything at all wrong with the code so would appreciate some feedback on the correctness of using return statements from within a switch block.

The following code compiles ok but gives the wrong output in a Release build on Win7 32-bit...

#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; } 

If you can repeat the problem, and have a MS Connect login, maybe you can vote it up here too?

Actual results

Release build gives the following incorrect result:

GetFloat() - entered GetFloat() - case 3 entered fValue = 0.000000 

Expected results

Debug build gives the following correct result:

GetFloat() - entered GetFloat() - case 3 entered fValue = 3.000000 

MS Connect bug report

like image 201
Roger Rowland Avatar asked Feb 12 '13 14:02

Roger Rowland


People also ask

Can you return out of a switch statement?

The JavaScript switch statement can contain return statements if it is present inside a function. The function will return the value in the switch statement and the code after the switch statement will not be executed.

Can switch case have duplicates?

If two cases in a 'switch' statement are identical, the second case will never be executed. This most likely indicates a copy-paste error where the first case was copied and then not properly adjusted.

Can switch statements use doubles in C?

The value of the expressions in a switch-case statement must be an ordinal type i.e. integer, char, short, long, etc. Float and double are not allowed. The case statements and the default statement can occur in any order in the switch statement.


2 Answers

It sounds like it might be this bug? Where there is a problem in returning floating point values generated in a similar way?

like image 136
jcoder Avatar answered Oct 03 '22 17:10

jcoder


Definitely a compiler error. Here is the stripped down asm code being executed (jumps etc. removed). The compiler removes some code it assumes to be unnecessary - even though it is not.


Release build:

// 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 

Debug build:

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 
like image 20
example Avatar answered Oct 03 '22 19:10

example