Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Switch/Case statement fun

Status
Not open for further replies.

chiph

Programmer
Jun 9, 1999
9,878
US
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:
Code:
switch(msgType)
{
   case MsgType.AddMsg:
   case MsgType.NewMsg:
      // Code here
      break;
   case MsgType.UpdateMsg:
      // more code
      break;
}
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.
msdn said:
switch (expression)
{
case constant-expression:
statement
jump-statement
[default:
statement
jump-statement]
}
This says that every case requires a jump-statement with it, where a jump-statement is one of: break continue default goto return.

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;
}
Obviously, that looks a little odd. But it meets the requirements of the spec!


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

    }
Compiling this, and running it thru Reflector produced this disassembled C# for case1
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;
}
and case2:
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 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
 
That's the dilemma -- the language spec says one thing, yet in reality it works differently.

And it shouldn't.

Chip H.


____________________________________________________________________
If you want to get the best response to a question, please read FAQ222-2244 first
 
Heh, I wouldn't get too worked up over it.

"Let he without sin throw the first stone"
Like your code documentation and code itself jive 100% of the time.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top