We discovered something interesting about the switch/case statement at work today. Ultimately, it didn't make any difference in the way the code ran, but it was interesting nontheless.
We had some (legacy) code that did something like this:
One of us remembered that in C# you can't "fall-through" case statements like you can in C or C++, so we looked up what the language spec said.
So, how was this working? The compiler was happy, even though there wasn't a jump-statement after the first case label. Theoretically, it should have looked like this:
Obviously, that looks a little odd. But it meets the requirements of the spec!
I created a test project that looks like this:
Compiling this, and running it thru Reflector produced this disassembled C# for case1
and case2:
The JIT optimizer rearrainged things, but I think you can see that with case 2, it replaced my goto with another break, and manipulated the structure some.
The debate about whether we're taking advantage of a JIT optimization (aka a side-effect of the compiler) or if this is a lazy-programmer optimization continues...
Chip H.
____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
We had some (legacy) code that did something like this:
Code:
switch(msgType)
{
case MsgType.AddMsg:
case MsgType.NewMsg:
// Code here
break;
case MsgType.UpdateMsg:
// more code
break;
}
This says that every case requires a jump-statement with it, where a jump-statement is one of: break continue default goto return.msdn said:switch (expression)
{
case constant-expression:
statement
jump-statement
[default:
statement
jump-statement]
}
So, how was this working? The compiler was happy, even though there wasn't a jump-statement after the first case label. Theoretically, it should have looked like this:
Code:
switch(msgType)
{
case MsgType.AddMsg:
goto case MsgType.NewMsg;
case MsgType.NewMsg:
// Code here
break;
case MsgType.UpdateMsg:
// more code
break;
}
I created a test project that looks like this:
Code:
class Class1
{
public enum MsgType
{
AddMsg,
NewMsg,
UpdateMsg
}
[STAThread]
static void Main(string[] args)
{
Class1 c = new Class1();
c.case1(MsgType.AddMsg);
c.case2(MsgType.AddMsg);
}
public int case1(MsgType msgType)
{
int i = 4;
switch(msgType)
{
case MsgType.AddMsg:
case MsgType.NewMsg:
i = i * 34;
break;
case MsgType.UpdateMsg:
i = i * 18;
break;
}
return i;
}
public int case2(MsgType msgType)
{
int i = 4;
switch(msgType)
{
case MsgType.AddMsg:
goto case MsgType.NewMsg;
case MsgType.NewMsg:
i = i * 34;
break;
case MsgType.UpdateMsg:
i = i * 18;
break;
}
return i;
}
}
Code:
public int case1(Class1.MsgType msgType)
{
int num1 = 4;
switch (msgType)
{
case Class1.MsgType.AddMsg:
case Class1.MsgType.NewMsg:
{
return (num1 * 0x22);
}
case Class1.MsgType.UpdateMsg:
{
return (num1 * 0x12);
}
}
return num1;
}
Code:
public int case2(Class1.MsgType msgType)
{
int num1 = 4;
switch (msgType)
{
case Class1.MsgType.AddMsg:
{
break;
}
case Class1.MsgType.NewMsg:
{
break;
}
case Class1.MsgType.UpdateMsg:
{
return (num1 * 0x12);
}
default:
{
return num1;
}
}
return (num1 * 0x22);
}
The debate about whether we're taking advantage of a JIT optimization (aka a side-effect of the compiler) or if this is a lazy-programmer optimization continues...
Chip H.
____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first