Is break needed if case is in parenthesis? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why was the switch statement designed to need a break?
I have this:
switch(i)
{
case a:
{
//code
}
case b:
{
//code
}
case c:
{
//code
}
}
If i == a, will the code in b and c be executed or must I put a break; in each one?
Thanks,

Must I put a break; in each one?
Yes, if you only want a single case to execute. Alternatively, other control flow statements can also cause a switch to be exited, like return or throw.
If you were to replace //code with, say, std::cout << "case [x]" << std::endl, the answer would be readily apparent.

yes, the breaks are needed for it to work correctly. The brackets only introduce a scope, they do not effect flow control.

Not in the last one, even though it is good practice to do so.
If you don't put in break in one, then the current case and all continuing cases will execute until the next break, throw, or return.
This is useful in cases where you want two case sections to execute the same code, you can write:
case a:
case b:
// ... some code...
break;
Which would execute for both a and b.

Related

Blocking inside a switch case

On an embedded system, running freertos, is there any reason why you would not have a blocking function inside a case of a switch statement?
For example, a thread running through a state machine and one of the states is a wait for a task notification.
Typically I've done this with if-else's but is there any advantage or disadvantage to making it a switch case?
Using cpp17 and avoiding STL.
Edit: blocking function, i.e. one that sits forever until it gets a notification, such as xTaskNotifyWait(...)
Example:
switch (state)
{
case state1:
foo();
break;
case state2:
xTaskNotifyWait(...);
};
vs
if (state == state1)
{
foo();
}
else if (state == state2)
{
xTaskNotifyWait(...);
}
TIA
You can use either a switch or if statement. There isn't much a difference. You can have blocking calls in either of them.
I've heard that switch cases use hash tables but if-else doesn't. I'm not sure if there are differences in the asm code, and what impact that would have on code size, speed, etc.
See this to understand the difference between switch and if statement. I am quoting one of the answer below:
The main difference is that switch despatches immediately to the case concerned, typically via an indexed jump, rather than having to evaluate all the conditions that would be required in an if-else chain, which means that code at the end of the chain is reached more slowly than code at the beginning.
That in turn imposes some restrictions on the switch statement that the if-else chain doesn't have: it can't handle all datatypes, and all the case values have to be constant.
With a switch construct, you can use descriptive enum for your case label which says that this state is meant to be blocking. I would personally use a switch construct as the case label can be descriptive.
enum state_e {
INIT,
WAITING_FOR_EVENT
};
switch (state) {
case INIT:
{
foo();
state = WAITING_FOR_EVENT;
break;
}
case WAITING_FOR_EVENT:
{
xTaskNotifyWait(...);
// Change State
break;
}
};

Why are these two statements equivalent

So my question basically has to do with a switch statement. Why is
switch (foo) {
case 1: case 2:
bar();
break;
}
the same as:
if (foo == 1 || foo == 2) {
bar();
}
It seems to me that with the switch statement, the code under case 1 would execute, and the code under case 2 would be ignored. Please explain to me why this is not the case.
When evaluating case statements, the code will fall through until the block is terminated (usually by a break statement). So the semantics of the first snippet are as follows:
If foo is 2, execute bar() and then break.
If foo is 1, execute the block following case 1:, which is empty (i.e., do nothing), and then continue (fall through) to the block following case 2:, detailed in the previous point
For any other value, do nothing (as there are no matching case blocks.
As you can see, this is equivalent of executing bar() in case foo is 1 or 2.
The break; statement is fully responsible for breaking out of the switch code block.
A switch statement without a break; statement will execute in a very odd order.
switch (2) {
case 2:
alert("hello");
case 3:
alert("goodbye");
break;
case 4:
alert("will never show");
}
JavaScript switch statements: https://www.w3schools.com/js/js_switch.asp
Add break; at the end of every case statement to stop a case from then executing everything below it. Otherwise, it falls through.

Switch statement with automatic break at each case step in C++

If we want to have a switch statement where for each case we need to run some instructions then break we would so something like this:
switch (condition) {
case (opt1):
// do stuff
break;
case (opt2):
// do stuff
break;
case (opt3):
// do stuff
break;
// ...
default:
// do stuff
}
Is it possible to have an exclusive switch, without fall through, where by default every option should break and not have to explicitly state the break instruction? And if not in C++ any idea if such a feature is available in other imperative languages?
C# needs the break too, but yells at you if you don't put it. You need to goto label; to explicitly fall through.
In C++, there is no way to do this natively (other than horrible macros, of course). However, Clang has the -Wimplicit-fallthrough warning. You can then insert [[clang::fallthrough]]; to silence the warning for a deliberate fallthrough.
Documentation : http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
I hate having break statements in my switches, so I use the pattern of wrapping a switch in a closure and returning from each case. For example:
auto result = [&] {
switch(enum_val) {
case A:
return Foo();
case B:
return Bar();
}
}();
"There is no automatic fall through" in Golang. https://golang.org/doc/effective_go.html#switch

Why use do { ... } while (FALSE); in C++ outside of macros [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Are do-while-false loops common?
Is there a reason to have code like:
do {
// a lot of code that only needs to be run once
} while (FALSE);
when the code isn't defining a macro? I know it's a trick when it comes to macros, but is there a reason for it in normal code?
Well, it does allow you to use the break; (or continue) keyword for early exit if you have a need for that for some reason. That would be kinda ugly though. I'd really rather see it moved into its own routine, with the early exit implemented via a return; statement.
Well one reason for it would be if you want to break out at some point.
i.e.
do
{
//some code that should always execute...
if ( condition )
{
//do some stuff
break;
}
//some code that should execute if condition is not true
if ( condition2 )
{
//do some more stuff
break;
}
//further code that should not execute if condition or condition2 are true
}
while(false);
In certain situations the resulting code is a little bit more clear / easier to understand if written as above.
Such a construct is used as a kind of goto to be able to jump after the end of the loop using a break statement inside.
I would not do this but:
I looks slightly more logical than just braces
int main()
{
{
std::ifstream file("Data");
// DO STUFF
} // Data now closed.
// LOTS OF STUFF SO YOU CANT SEE file2 below.
// We can re-use data here as it was closed.
std::ofstream file2("Data");
// DO STUFF
}
An unobservant maintainer may see the braces and think.
What the heck and remove them
int main()
{
std::ifstream file("Data");
// DO STUFF
// LOTS OF STUFF SO YOU CANT SEE file2 below.
// FAIL. data is still open from before.
std::ofstream file2("Data");
// DO STUFF
}
I suppose using the while tick at least make syou think about it (though an unobservant maintainer may still remove it).
int main()
{
do
{
std::ifstream file("Data");
// DO STUFF
} while (false);
// LOTS OF STUFF SO YOU CANT SEE file2 below.
// We can re-use data here as it was closed.
std::ofstream file2("Data");
// DO STUFF
}
There is no reason to ever write a loop that is known, at compile time, to execute exactly once.
Doing so, in order to pretend that goto is written as break, is abusive.
EDIT:
I've just realised that my assertion about compile-time knowledge is false: I suppose you might do something complicated with conditional #defines that might mean that, at compile time for one build configuration, it is known to execute once, but for a different build configuration, it is executed multiple times.
#ifdef SOMETHING
#define CONDITION (--x)
#else
#define CONDITION 0
#endif
...
int x = 5
do{
...
} while(CONDITION)
However, the spirit of my assertion still stands.
It can be used to implement a behavior similar to goto statement, or say jump behavior!
See this:
do
{
if (doSomething() != 0) break; //jump
if (doSomethingElse() != 0) break; //jump
...
if (doSomethingElseNew() != 0) break; //jump
} while(false);
//if any of the break encountered, execution can continue from here, just after the do-while block!
// statement1
// statement2
// statement3
// so on
Taken from here: Are do-while-false loops common?

Using continue in a switch statement

I want to jump from the middle of a switch statement, to the loop statement in the following code:
while (something = get_something())
{
switch (something)
{
case A:
case B:
break;
default:
// get another something and try again
continue;
}
// do something for a handled something
do_something();
}
Is this a valid way to use continue? Are continue statements ignored by switch statements? Do C and C++ differ on their behaviour here?
It's fine, the continue statement relates to the enclosing loop, and your code should be equivalent to (avoiding such jump statements):
while (something = get_something()) {
if (something == A || something == B)
do_something();
}
But if you expect break to exit the loop, as your comment suggest (it always tries again with another something, until it evaluates to false), you'll need a different structure.
For example:
do {
something = get_something();
} while (!(something == A || something == B));
do_something();
Yes, continue will be ignored by the switch statement and will go to the condition of the loop to be tested.
I'd like to share this extract from The C Programming Language reference by Ritchie:
The continue statement is related to break, but less often used; it causes the next iteration of the enclosing for, while, or do loop to begin. In the while and do, this means that the test part is executed immediately; in the for, control passes to the increment step.
The continue statement applies only to loops, not to a switch statement. A continue inside a switch inside a loop causes the next loop iteration.
I'm not sure about that for C++.
Yes, it's OK - it's just like using it in an if statement. Of course, you can't use a break to break out of a loop from inside a switch.
It's syntactically correct and stylistically okay.
Good style requires every case: statement should end with one of the following:
break;
continue;
return (x);
exit (x);
throw (x);
//fallthrough
Additionally, following case (x): immediately with
case (y):
default:
is permissible - bundling several cases that have exactly the same effect.
Anything else is suspected to be a mistake, just like if(a=4){...}
Of course you need enclosing loop (while, for, do...while) for continue to work. It won't loop back to case() alone. But a construct like:
while(record = getNewRecord())
{
switch(record.type)
{
case RECORD_TYPE_...;
...
break;
default: //unknown type
continue; //skip processing this record altogether.
}
//...more processing...
}
...is okay.
While technically valid, all these jumps obscure control flow -- especially the continue statement.
I would use such a trick as a last resort, not first one.
How about
while (something = get_something())
{
switch (something)
{
case A:
case B:
do_something();
}
}
It's shorter and perform its stuff in a more clear way.
Switch is not considered as loop so you cannot use Continue inside a case statement in switch...