Using continue in a switch statement - c++

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...

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

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

C++ Will all code inside a nested 'if' statement run, even if that changes the boolean value of the outside statement?

I have a couple of if statements in my C++ code (one nested inside the other), and I want to be sure that they will run as I expect- the code is:
if(state == entry){
if(abs(distance < 0.05){
state = arcing;
...
startAngle = positionAC;
}
// Some more statements here...
}
If the second if statement condition is met, will the code where my comment "// Some more statements here..." be run now that the value of state has changed to arcing rather than entry? I would have thought that they should be run because the code will still be executing from when the first condition was true, even though it now no longer will be. Is this correct?
The if-check
if(state == entry)
will be performed exactly once, at the moment that line is reached in the code.
From then on, it doesn't matter if the values of state or entry are modified - the entirety of the code inside the if-block will be executed, if state was equal to entry when that line was reached.
Yes. I remember once having this doubt about the Pascal while loop. The text book we had didn't describe the workings of the loop in very concrete terms, but only that it iterated “while” the condition was true. Some experimentation convinced me that the condition was only checked once per iteration, namely at the start of the loop. But the thing is, I should not have had to check that: the book should have been clear on that.
So, clarity:
A C++ if statement like
if( condition )
{
action_1;
action_2;
action_3;
}
something_more;
is 1equivalent to:
const bool do_it = condition; // The single evaluation of condition
if( do_it ) goto do_actions;
goto do_more_things;
do_actions: // Just a name for this place in the code, a "label".
action_1;
action_2;
action_3; // The next executed statement is something_more.
do_more_things:
something_more;
And yes, both are valid C++ code.
1) This equivalence ignores possible name collisions, and it assumes that none of the actions are declarations. Declarations can foil the equivalence in two ways. First, it's not permitted to goto-jump over a declaration that executes initialization and that's in scope at the point jumped to. Second, destructors are executed when the execution leaves a block, and to capture that one has to imagine that those destructor executions are among the actions.
If the condition in the if statement
if(state == entry){
will be evaluated to true (it is evaluated only once in this point) then the compound statement of the if will be executed.
The statements under the comment will be executed exactly once, unless the first condition itself is NOT within a loop, or a method which is called recursively.
But if you want to make sure that the code after the comment is executed only when the state == entry at that point of time you can change your code as below
if((state == entry) && (abs(distance < 0.05)) {
state = arcing;
...
startAngle = positionAC;
}
else if (state == entry)
{
// Some more statements here...
}

Two for loops and an if statement inside it

My code is something like this:-
for() //outer for
{
for() //inner for
{
if()
{
break;
}
}
}
If the break statement executes the next execution will be of which for loop?
I know this is a very abstract question but I really don't have time to write the full code. Thanks.
break will break the inner for **loop** only. It breaks the closest loop ONLY where it was called.
In your example, if your if condition is satisfied, it will stop iterations of the inner for loop and move back(continue) the outer for loop.
The break statement terminates the execution of the nearest enclosing do, for, switch, or while statement in which it appears. In this case, that means breaking out of the inner for only.
Edit: Standard Reference: 6.6.1 The break statement [stmt.break]
1 The break statement shall occur only in an iteration-statement or a
switch statement and causes termination of the smallest enclosing
iteration-statement or switch statement; control passes to the
statement following the terminated statement, if any.
You can use goto to break the outer loop as well if you like.
You'll need a way to break the outer loop as the break will only leave its enclosing scope. What you use to manage state can be anything, but in its most simple form you can just use a boolean and check for that as well as your original condition in the outermost loop.
bool breakLoop = false;
for(...; ... && !breakLoop; ...) //outer for
{
for() //inner for
{
if()
{
breakLoop = true;
break;
}
}
}

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

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.