Select Case Statement

Mar 31, 2009 at 4:21 PM
Edited Mar 31, 2009 at 4:22 PM
I first noticed this issue when I was trying to get Cosmos to work in VB.NET. Every time I would use a Select Case statement I would always get "Multidimensional arrays are not yet supported!" when trying to Debug (F5) the project.

Here is the really weird thing. I thought it was just an issue with how the compiler was handling VB.NET so I switched to C#. I have an ExecuteCommand subroutine that is processing what has been typed in and executes it. Kinda like a Windows Command Prompt. This subroutine contains a VERY simple switch statement like the following:

        public static void ExecuteCommand(string command)
        {
             switch (command)
             {
                case "CLEAR":
                     Console.Clear();
                     WritePrompt("");
                     break;
                case "HELP":
                     DisplayHelp();
                     WritePrompt("");
                     break;
                case "TEST":
                     TestSub();
                     break;
                case "SHUTDOWN":
                     Shutdown();
                     break;
                case "REBOOT":
                     Reboot();
                     break;
                default:
                     Console.WriteLine("---> Unknown Command");
                     WritePrompt("");
                     break;
             }
        }

This works beautifully. Now here is the issue. When I add one more case for the word "ABOUT" like this:

        public static void ExecuteCommand(string command)
        {
             switch (command)
             {
                case "CLEAR":
                     Console.Clear();
                     WritePrompt("");
                     break;
                case "HELP":
                     DisplayHelp();
                     WritePrompt("");
                     break;
                case "TEST":
                     TestSub();
                     break;
                case "SHUTDOWN":
                     Shutdown();
                     break;
                case "REBOOT":
                     Reboot();
                     break;
                 case "ABOUT":
                     DisplayAbout();
                     WritePrompt("");
                     break;
                default:
                     Console.WriteLine("---> Unknown Command");
                     WritePrompt("");
                     break;
             }
        }

I get the error "Multidimensional arrays are not yet supported!". The DisplayAbout subroutine contains 3 Console.WriteLine statements, so I don't see how it could be this. I have also changed the word ABOUT to A and other random characters and I still get the error. Does anyone have any idea what is causing this?
Developer
Mar 31, 2009 at 6:59 PM
Hi

Could you post those 3 Console.WriteLine statements? This may seem funny, but I had exactly the same issue as you, and it did turn out to be a Console.WriteLine problem. I had gotten accustomed to .NET always automatically doing the .ToString() for me. On one variable it didn't work, and thats what caused that error. Not sure if it can be related to your problem. I basically added the .ToString() to the variable, and the error was gone.
Mar 31, 2009 at 7:08 PM
Below is the subroutine that is being called. I don't think it is the WriteLine statements. I honestly think its an issue how switch and/or select case statements are being handled:

        public static void DisplayAbout()
        {
            Console.WriteLine("____________________________ABOUT OS______________________");
            Console.WriteLine("     OS is in very early development stages and ");
            Console.WriteLine("     currently does not support anything but text graphics.");
            Console.WriteLine("     OS comes with no warranty or support!");
        }
Developer
Mar 31, 2009 at 9:47 PM
Yeah, I can say with reasonable certainess that the problem is not the same thing I had. Perhaps try to add only the case statement without calling DisplayAbout(), and see if you still get the error. If you do, then I don't know, and you will have to wait for somebody smarter than me to reply
Mar 31, 2009 at 9:53 PM
Edited Mar 31, 2009 at 9:53 PM
Yeah, I found out the "cause" of the problem. It happens anytime you have more then 6 cases in a switch statement in C#. Which is REALLY odd and I have no idea what the fix would be...
Apr 1, 2009 at 8:54 PM
Do I just wait for a developer to respond or how do I find out what is going on?
Developer
Apr 1, 2009 at 9:30 PM
Well, you could download the dev kit and see if you can figure out whats wrong, but otherwise yeah, it would need to be one of the devs working on the compiler that would need to help you out. I am relatively sure it had something to do with the fact that you are using strings for the case statements, and not directly related to switch itself, as there are places in the code where there are way more than 6 cases in a switch statement, and it works.

I have a suspicion it has something to do with hash functions and them not working yet. Most likely when you reach a certain threshold of case <string> statements, the compiler reckons it would be more efficient to use a hash table to pick the outcome than multiple if statements, and thats when it bombs out, since it can determine the hash of the strings.
Apr 1, 2009 at 9:50 PM
Is it the VS compiler or the Cosmos compiler that is doing it...

If it is the VS compiler is there any way to disable it from turning the switch statement into a hash table?

Stupid question I know.
Apr 1, 2009 at 11:25 PM
Have you guys ever heard of a tool called Reflector? Or by any chance ILDASM?

Go check what IL code C# compiler generates for that or other switch statement case. You'll save yourself a lot of time and have bunch of joy snooping around class libraries' internals. If knowledge is power, Relfector is one hell of energizer.
Apr 2, 2009 at 1:15 AM

I've used reflector before. I have to agree, it is an AWESOME util. I create a very simple C# console app with a subroutine that has a 7 case deep switch statement which looks like this:

static void SelectCommand(string cmd)

{

switch (cmd.ToUpper())

{

case "STRINGONE":

Console.WriteLine("One");

break;

case "STRINGTWO":

Console.WriteLine("Two");

break;

case "STRINGTHREE":

Console.WriteLine("Three");

break;

case "STRINGFOUR":

Console.WriteLine("Four");

break;

case "STRINGFIVE":

Console.WriteLine("Five");

break;

case "STRINGSIX":

Console.WriteLine("Six");

break;

case "STRINGSEVEN":

Console.WriteLine("Seven");

break;

case "STRINGEIGHT":

Console.WriteLine("Eight");

break;

default:

break;

}

Console.ReadLine();

}

Now the IL code, for example, for case "STRINGONE" looks like this:

    L_001d: ldstr "STRINGONE" L_0022: ldc.i4.0 L_0023: call instance void [mscorlib]System.Collections.Generic.Dictionary`2<string, int32>::Add(!0, !1)
    L_0028: dup

Now to me, that looks like the switch statement is being converted to a Dictionary...

Now if the switch statment has less the 6 cases it looks like this:

    L_000a: ldloc.0
    L_000b: ldstr "STRINGONE"
    L_0010: call bool [mscorlib]System.String::op_Equality(string, string)
    L_0015: brtrue.s L_0033

Now to me it appears it is keeping them as strings... 

Any ideas how to not allow the compiler to convert the switch statments to dictionaries?

Developer
Apr 2, 2009 at 5:44 AM
For starters, make sure the "Optimize Code" tick box on the Build tab of the Project properties is unticked. If it is, and you still have the problem, then if possible at all, it would most likely be a compiler command line switch.
Apr 2, 2009 at 1:42 PM
Well I turned off Optimize Code and it is still doing it. I'm not even sure on how to approach the appropriate search terms needed to find the answer on how to "turn it off"...
Coordinator
Apr 3, 2009 at 10:59 AM
Apparently, the Microsoft C# compiler uses dictionaries for larger case statements using strings. Dictionary<K,V> has two issues on Cosmos: it uses hashes and it uses multidimensional arrays. Both are not supported yet. (Hashes use floats most of the time, which are the unsupported part..) 
We plan to do this is the somewhat near future, but we have other important things too, and we have limited man-power on the compiler part of the project. If you're interested in joining, please do so ;-)