Branching in switch statement

Started by
35 comments, last by wack 10 years, 2 months ago

There is something called a coroutine, which is a piece of code that you can call, will do a piece of the work, return and the next time you call it will pick up where it left off. There are languages that explicitly support that paradigm (go is a modern example). Others support it through libraries, but you can always roll your own, using the type of code discussed in this thread.

Speaking of coroutines, I have been toying with a method to implement AI for a very general class of board games, where you would implement the rules as a coroutine that returns every time any players need to make decisions. The next call will get the decisions as parameters and continue with the game until another decision point is reached. I am trying to do this in C++ using longjmp. It's a horrible hack, but I love it. :)

Advertisement

That looks interesting. I did not know abaut corutines.

In FSM for states I used enums and I would switch to a new state trough case statements. But I think functions could be also part of a state so functions could have the same name as a state. So if we need to switch to another state without using while we could just call another state function.

you do not have to write a break in case's body. Runtime behaviour of switch is that it examines every case condition from first-top most to next, and if it finds fitting condition it enters the case's body, and if the break command is present it leaves switch{} body at that point, not examining other conditions. If no condition is met, the last case: should be so called defaut:. This is body that will execute for any value, so it should be last, to assure it is executed for any not found value (most usualy).

lets move to what you are after though I see it shady, but I believe it is this:

switch(somevalue)
{
case somevalue1:
Function1();
Function2();
break;
case somevalue2:
Function2();
break;
}

or

switch(somevalue)
{
case somevalue1:
Function1();
case somevalue2||somevalue1:
Function2();
break;
}

somevalue2 will run Function2() always, somevalue1 will run Function1(); Function2(); - in both those example variations.

For the nature of switch statement, I avoid using it , I have actualy never used it. I rather write nested if's in case of more skip-branching. So I do not know for sure that missing break will result in evaluating next case, or , entering it. Someone might confirm the second example.

you do not have to write a break in case's body. Runtime behaviour of switch is that it examines every case condition from first-top most to next, and if it finds fitting condition it enters the case's body, and if the break command is present it leaves switch{} body at that point, not examining other conditions. If no condition is met, the last case: should be so called defaut:. This is body that will execute for any value, so it should be last, to assure it is executed for any not found value (most usualy).

lets move to what you are after though I see it shady, but I believe it is this:

switch(somevalue)
{
case somevalue1:
Function1();
Function2();
break;
case somevalue2:
Function2();
break;
}
or
switch(somevalue)
{
case somevalue1:
Function1();
case somevalue2||somevalue1:
Function2();
break;
}
somevalue2 will run Function2() always, somevalue1 will run Function1(); Function2(); - in both those example variations.

For the nature of switch statement, I avoid using it , I have actualy never used it. I rather write nested if's in case of more skip-branching. So I do not know for sure that missing break will result in evaluating next case, or , entering it. Someone might confirm the second example.


Specifically to C#, you cannot 'fall through' like you can in C and C++, EXCEPT if the starting case statement is completely empty.

In other words:


// This will compile in C#, C and C++:
switch (v)
{
  case 0:
  case 1:
    DoStuff();
    break;
}

// This will not compile in C#, but will in C and C++:
switch (v)
{
  case 0:
    DoStuff();
  case 1:
    DoMoreStuff();
    break;
}

yes, for me switch was so undefintive clear even in cpp . very vague interpretation of it among compilers or platforms, and when I realized I will never need it , I simply never implemented it. I have enough stress from my code already, lol

I have never heard of vague interpretations of switch-statements in C++ compilers. Care to elaborate?
I think he means that he's sick of different languages having completely different rules and behavior for switch statements. (It seems like a pretty minor complaint to me once you learn which style a particular language uses.)

His first post describes how switches work in Javascript, PHP and AS3 (and perhaps other languages that don't care about being optimal). A switch statement in those languages are just syntactic sugar for an if/else chain.

You can even do ridiculous things like this (which I have personally seen in professional AS3 web games)...


switch (true)
{
    case x < 0:
    case y < 0:
    case x >= width:
    case y >= height:
        return;

    default:
        DoStuff();
        break;
}
...which is utter blasphemy for people with C/C++ backgrounds. I haven't seen anyone crazy enough to find out whether assignment expressions work within case statements in those languages, but I would not be surprised.

In C and C++, the compiler can build low-level jump tables if it meets certain criteria, otherwise it builds an optimized if/else binary tree. Case statements cannot be full expressions like in JS/AS3/PHP.

In C#, most of the same behavior from C and C++ carry over, except that complex fallthroughs must be made explicit by using 'goto case' (this is an attempt to prevent bugs with forgotten breaks). Case types are restricted to consts/literals like in C and C++, but strings are OK as well. .Net's x86 JIT step can produce low-level jump tables like C and C++.

The more case statements, the more performance increases in the efficiency-conscious languages compared to what you get in the "let's do it the simple way" languages.

I have never heard of vague interpretations of switch-statements in C++ compilers. Care to elaborate?

I first aproached switch in my programing milk days in c++ language. I was trying to learn it but I got quite confused of it already, it was unclear to me how it exactly executes, and also applying :, which seemed to me as a keyword, not an operator, was making it quite a too much of an uncomfortable thing just to branch on some value. Maybe it even produces goto instructions when compiled, do not know, I suspect switch of anything. When I was learning to program, I had to have exact knowledge of every instruction. its definition and abstract. I pretty soon discoverd that switch is an instruction that has nothing exclusive to the rest of instructions so I realized I will never need it. Many programers rumble about goto instruction being the same case too, perhaps a fact you will never need it is enough for a programer to ban using it, and force smaller atomic clearer instructions to be written instead.

void switch22(value)

{

if (value&0)

{

dozero();

return;

}

if (value<0)

{

donegative();

return;

}

dobiggerzero();

return;

}

I pretty soon discoverd that switch is an instruction that has nothing exclusive to the rest of instructions so I realized I will never need it.

Ehmmm.... actually... that is not quite right... switch does have something exclusive. A switch statement can - quite often - be realized through a jump table or something similar (performance!). I don't know of any compiler that can do that for a nested if statement (which is the only alternative to a switch). I have implemented quite a lot of programming languages myself (high level languages... Java, C#, Smalltalk, Javascript, some custom scripting languages) and I can assure you: If it's possible, use "switch" instead of nested IFs. It is very likely to be faster. I only talked about "interpreted" languages (the quotes are due to the fact that, of course, nowadays those are not really interpreted anymore, but just-in-time-compiled), but if I remember correctly from some previous posts from you, you are using C++... the thing about the jump table does also apply to C++ (which, in general, is not interpreted nor JIT'ed)

Beginners may be reading this thread, so I feel like it's time to deal with some misinformation.


and also applying :, which seemed to me as a keyword, not an operator...


You should learn about how languages are parsed to more clearly understand what you're talking about. The colon in a switch statement is a 'token' which is an integral part of the case statement syntax, and is neither a keyword nor an operator. Guessing what something means without doing research to find out if your guess is correct or not isn't a very good way to learn programming.

Maybe it even produces goto instructions when compiled, do not know, I suspect switch of anything. When I was learning to program, I had to have exact knowledge of every instruction. its definition and abstract.


That kind of knowledge can be gained as simply as placing a breakpoint on a C/C++ switch statement and opening a disassembly window to see what assembly instructions are present. It's no use trying to speculate or guess what could be happening when you can ACTUALLY SEE what's happening if you look in the right place.

I pretty soon discoverd that switch is an instruction that has nothing exclusive to the rest of instructions...


The jump table built by switch statements in some languages is not possible to reproduce in those languages without using inline assembly. No language I know of allows you to declare an array of intrafunction labels and say "goto array[labelIndex];" (that's pseudocode of what a single-lookup table-based switch does in C and C++).

The closest you can get in C and C++ is an array of function pointers, but those incur the cost of calling the function and passing parameters. With a jump table, you don't leave the function, so you don't incur any function call overhead. The compiler is also much more free to rearrange the control flow graph and share common groups of statements in separate switch blocks.

...instruction...
...atomic...


I realize that English probably isn't your native language, but you should really make sure you get your terminology correct. Having discussions with other programmers becomes difficult if everyone decides to use words that mean different things to everyone else.

This topic is closed to new replies.

Advertisement