I have found a following piece of code:
switch(val){
case 0:
// some actions
break;
case 1:
// some actions
break;
case 2:
// some actions
break;
}
But it is not clear enough what will happen in the case of e.g val = 10?
I tried to test this code in a short program with incorrect value, and nothing had happen - program exited normally.
Can this code cause any potential error? Is there any guarantee that nothing will happen?
It will simply do nothing and not enter in any case.
It is recommended to have a default clause as the final clause in a switch statement. Programs like Lint will warn if you forget the default clause. And for information note that the default clause is required in MISRA-C.
EDIT:
I personally prefer it to be the final clause but I think the most important is for the final clause to be present. Why I prefer it to be the final clause is because of the Principle of least astonishment: people are used to see it as the final clause so I think it eases the program reading.
And just for information as I mentioned Lint and MISRA-C in my answer: PC-Lint / flexelint will not warn if default is present but not as the final clause and MISRA-C explicitly requires default to be present as the final clause.
That is why you should have a default case. It will handle cases other than those you typed.
What Happens in your case is that, it checks the case 0 and it doesn't match and checks case 1 and it also doesn't match and checks the case 2 and it again doesn't match. so it exits..
So it should be this way:
switch(val){
case 0:
// some actions
break;
case 1:
// some actions
break;
case 2:
// some actions
break;
default:
//some actions
break;
}
Another small point to note: it should case 0: not case 0;
If you use any other value from 0, 1, 2 (in this example) nothing will happen.
val will be compared with all values that are in cases and if it will not be equal to one of them, it just will jump to the next statement.
Related
I have a switch in which I check a property of some sort and if the check yields a specific value, I want to check another value, so I did something like this:
switch(property_A)
{
case NA:
if(value_0 == property_B)
property_A = value_a;
else if(value_1 == property_B)
property_A = value_b;
case value_0:
...
break;
case value_1:
...
break;
}
So, I know this solves my problem, but I don't know if this is a good idea or maybe should I go about this another way
# the NA case is something like a default case but not exactly, because it does tell me something, but not enough
It depends on what you want to do. If you get to the case NA, without the break keyword, the value_0 case will be executed after one of the two if branches is finished. So if that's the behaviour you want, it's OK not to use break, but I don't think that's what you wanted to do.
I suggest you simply move the if - else statement above the switch and remove the NA case. This way, you will first assign the correct data to property_A and then you can do whatever you want with it in the switch.
EDIT: As Jack Deeth points out, if you omitted the break statement on purpose, it's a good idea to add a comment that you did so.
Convention is to add a comment explicitly telling future-you and any other maintainers you intended the fallthough and you haven't accidentally omitted the break;.
switch(foo) {
case 1:
bar();
// fallthrough
case 2:
baz();
break;
case 3:
fizzbuzz();
}
If you're using C++17 or later you can use the [[fallthrough]] attribute to avoid a compiler warning:
switch(foo) {
case 1:
bar();
[[fallthrough]]
case 2:
baz();
break;
case 3:
fizzbuzz();
}
The additional information provided in the comments to the question indicate that what's wanted is not what's written in the question:
switch(property_A)
{
case NA:
if(value_0 == property_B)
property_A = value_a;
else if(value_1 == property_B)
property_A = value_b;
// here, we fallthrough into the code for value_0
// but you want to switch on the new value instead
case value_0:
...
break;
}
What you say you actually want is to set property_A if it was initially NA, then jump to the correct label. In that case, you'll need the assignment to be outside of the switch statement. You could do this with a goto at the end of the NA case, but I recommend you just deal with the NA before the switch:
if (property_A==NA)
property_A = (value_0 == property_B) ? value_a
: (value_1 == property_B) ? value_b
: NA;
switch (property_A) {
case value_0:
...
break;
case NA:
// we get here only if none of the replacement conditions
// matched, outside the 'case'
}
I was musing over a switch statement I had written for 4 mutually exclusive cases. I inserted a break statement at the end of each case, because I didn't want to do the test again after one case or another had been successful.
Here's the question, though. What, if anything, does the last break do? If the test case 43 succeeds, the break terminates the case, but if there's no break, the default shouldn't run, and so there's no wasted test anyway.
Here's the code:
switch(telemetry) {
case(40):
printf("\nHouse Telemetry #%i \n", psc);
break;
case(41):
printf("\nNav Telemetry #%i \n", psc);
break;
case(42):
printf("\nDownhill Telemetry #%i \n", psc);
break;
case(43):
printf("\nRealTime Telemetry #%i \n", psc);
break; // what do I do?
default:
printf("\nCommand ID not recognized\n");
}
Perhaps one of you compiler gurus can advise me.
If you did not have the break; in case 43, it would fall through to the default case, and also execute the printf("\nCommand ID not recognized\n");.
Why do you think the default would not run? switch-case will continue execution until it encounters a break statement, and this includes the default section.
The break therefore is required for the desired behavior.
Putting a break; on the very last element of a switch-case (whether it is default or case) is optional, as it would stop execution that is coming to an end anyway.
I've encountered programmers who feel both ways about it: That there should not be an extra break at the very end of the block because it is not necessary, or that there should be one for consistency, and on the possibility that the sections get re-arranged in the future.
A switch statement is not a language construction that divides codes into separate cases. It is a computed “go to” statement: Based on the switch expression, it causes program control to jump to one of the labels.
Once that jump is completed, the switch does not exercise any further control over execution. It does not separate cases from one another or insert jumps or returns at the end of each case. Therefore, if you want control to leave the code for one case and not flow into the following code for another case, you must insert a break or other instruction that affects program control (such as return).
This characteristic of switch statements makes possible uses such as:
switch (letter)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
printf("Vowel.\n");
break;
default:
printf("Consonant.\n");
break;
}
Observe there are five case labels using one section of code. If the switch automatically separated them, the first four would be empty; nothing would be done for them when letter was a, e, i, or o.
Another example is where one case does some preparation work and then falls into another case, such as:
switch (operation)
{
case Subtract:
b = -b;
case Add:
result = a+b;
break;
case Multiply:
result = a*b;
break;
}
Here the Add case adds two numbers, and the Subtract case works by negating b and then continuing into the code for the Add case. This could not work if the switch automatically separated cases. (This is a simplified example, of course.)
The break keyword in each case indicates the end of a particular case. If we do not put the break in each case then even though the specific case is executed, the switch in C will continue to execute all the cases until the end is reached. This should not happen; hence we always have to put break keyword in each case. Break will terminate the case once it is executed and the control will fall out of the switch.
I have below switch case in my code.
switch(condition)
case 'A' :
//Code part A
break;
case 'B' :
//Code part A
//Code part B
break;
case 'C' : //Some code
break;
code Part A is repeated in both case 'A' and case 'B'. I want to avoid duplication of code.
If we use fall though then we need to add an if condition for case B. Is this the only way for avoiding repetition of code?
If the order is not important, you can simply do:
switch (condition)
{
case 'B':
// Code part B
// no break
case 'A':
// Code part A
break;
...
}
A case 'B' will continue to execute through the case 'A' code because you didn't call a break.
Manipulating a switch statement to reduce duplication of code may work at first, but then you may add additional cases to the switch later, which may break that cleanness of that optimization. For example:
switch(condition)
case 'A' :
// Code part A
break;
case 'B' :
// Code part A
// Code part B
break;
case 'C' :
// Code part C
break;
case 'D' :
// Code part A
// Code part D
break;
Suddenly an optimization which seemed nice at the time, starts to become difficult to maintain, difficult to read and error prone.
Having already determined that there is common code, the cleanest response in my view is to write functions to perform the common code and call from each case. Going forward, this will continue to be maintainable.
Unfortunately, that's the only way, short of defining a function for partA.
You can reduce nesting by exiting the switch from inside the combined case label to make the code look a little more uniform:
switch (someValue) {
case 'A':
case 'B':
// Code part A
if (someValue == 'A') break;
// Code part B
break;
case 'C':
break;
}
This lets your part A and part B code have the same level of nesting.
Can "//Code part B" be executed before "//Code part A"? If so, you could just reorder them and let it fall through without an if condition.
I don't think there's much else to do, otherwise. One of the reasons for the creation of object-oriented languages was avoiding the duplication of code you have in imperative languages.
Quick question. For example, working with a some-what larger case of ~1000 options: which is the 'best' method? I'm not specifically wanting straight up faster results.
switch (foo) {
case 0:
// code ...
break;
// One, two, skip a few...
case 1000:
// code ...
}
or something that splits possible results so it can quickly find the proper case statement. Similar too:
if (foo < 101) {
if (foo < 51)
switch (foo) {}
else
switch (foo) {}
} else if (foo > 100 && foo < 201) {
// skipped for convenience
} else if (foo > 900) {
if (foo < 951)
switch (foo) {}
else
switch (foo) {}
}
I imagine the second method is much faster for the larger numbers, but the first method also seems it may be able to breeze through it since it's not constantly checking statements. Is one of these methods frowned upon or is there a better method? This is for C, but I am interested in knowing its consistency with other languages. Thanks!
switch statements can be incredibly fast if the compiler implements them using jump tables, but this is only possible on special sequence of cases, and may not be practical it really depends on the possible cases. The compiler may or may not use jump tables, I did find this http://blog.jauu.net/2010/06/15/GCC-generated-Switch-Jump-Tables/ which was kind of interesting.
JUMP tables can be incredibly fast, since it just calculates the offset and jumps to the appropriate address.
GCC does have -fno-jump-tables which does disable it completely.
Sometimes you can build your own jump table, using arrays of function pointers, and special indices, this can make your code incredibly fast but its not practical in all cases, imagine you had a switch and in every case you would call a function, you could build an array of function pointers, set a default function just to be safe, then instead of a switch you would simply do fun_table[indice](); I did this once for my own virtual machine.
I think switch statements are often interpreted as goto's in the underlying assembly language, which would make the first method significantly faster.
This seems to support that, although it isn't exactly proof: http://en.wikibooks.org/wiki/Optimizing_C%2B%2B/Writing_efficient_code/Performance_improving_features#Case_values_of_switch_statements
I believe that the switch statement is better, at least from a code readability standpoint (and maybe from a speed standpoint since it's only picking out one block to run as apposed to have to evaluate multiple conditions, as in the second example.)
Is it not recommended that any function should fit onto about 1.5 screens, so such a huge switch statement will not fit this bill. To overcome this have a dispatch table.All you have to do is index into the array to find the appropriate function to call.
I'm posting this just for information purpose, since samy.vilar already gave the most elegant solution with the function array. If you use GCC, it understands case range. This code would eventually behave in quite similar way as your second solution, resulting in some binary-tree code path (assuming there is no compiler optimization).
int nested_switch(int i)
{
switch (i) {
/* i is in the 1..10 range */
case 1 .. 10:
switch (i) {
/* i is in the 0..5 range */
case 1 .. 5:
switch (i) {
case 1:
break;
case 2:
break;
...
case 5:
break;
}
case 5 .. 10:
switch (i) {
case 6:
break;
case 7:
break;
...
case 10:
break;
}
}
/* i is in the 11..20 range */
case 11 .. 20:
switch (i) {
...
}
}
return 0;
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
Let's say I have code in C with approximately this structure:
switch (something)
{
case 0:
return "blah";
break;
case 1:
case 4:
return "foo";
break;
case 2:
case 3:
return "bar";
break;
default:
return "foobar";
break;
}
Now obviously, the breaks are not necessary for the code to run correctly, but it sort of looks like bad practice if I don't put them there to me.
What do you think? Is it fine to remove them? Or would you keep them for increased "correctness"?
Remove the break statements. They aren't needed and perhaps some compilers will issue "Unreachable code" warnings.
I would take a different tack entirely. Don't RETURN in the middle of the method/function. Instead, just put the return value in a local variable and send it at the end.
Personally, I find the following to be more readable:
String result = "";
switch (something) {
case 0:
result = "blah";
break;
case 1:
result = "foo";
break;
}
return result;
I would remove them. In my book, dead code like that should be considered errors because it makes you do a double-take and ask yourself "How would I ever execute that line?"
Remove them. It's idiomatic to return from case statements, and it's "unreachable code" noise otherwise.
Personally I would remove the returns and keep the breaks. I would use the switch statement to assign a value to a variable. Then return that variable after the switch statement.
Though this is an arguable point I've always felt that good design and encapsulation means one way in and one way out. It is much easier to guarantee the logic and you don't accidentally miss cleanup code based on the cyclomatic complexity of your function.
One exception: Returning early is okay if a bad parameter is detected at the beginning of a function--before any resources are acquired.
I'd normally write the code without them. IMO, dead code tends to indicate sloppiness and/or lack of understanding.
Of course, I'd also consider something like:
char const *rets[] = {"blah", "foo", "bar"};
return rets[something];
Edit: even with the edited post, this general idea can work fine:
char const *rets[] = { "blah", "foo", "bar", "bar", "foo"};
if ((unsigned)something < 5)
return rets[something]
return "foobar";
At some point, especially if the input values are sparse (e.g., 1, 100, 1000 and 10000), you want a sparse array instead. You can implement that as either a tree or a map reasonably well (though, of course, a switch still works in this case as well).
If you have "lookup" type of code, you could package the switch-case clause in a method by itself.
I have a few of these in a "hobby" system I'm developing for fun:
private int basePerCapitaIncomeRaw(int tl) {
switch (tl) {
case 0: return 7500;
case 1: return 7800;
case 2: return 8100;
case 3: return 8400;
case 4: return 9600;
case 5: return 13000;
case 6: return 19000;
case 7: return 25000;
case 8: return 31000;
case 9: return 43000;
case 10: return 67000;
case 11: return 97000;
default: return 130000;
}
}
(Yep. That's GURPS space...)
I agree with others that you should in most cases avoid more than one return in a method, and I do recognize that this one might have been better implemented as an array or something else. I just found switch-case-return to be a pretty easy match to a lookup table with a 1-1 correlation between input and output, like the above thing (role-playing games are full of them, I am sure they exist in other "businesses" as well) :D
On the other hand, if the case-clause is more complex, or something happens after the switch-statement, I wouldn't recommend using return in it, but rather set a variable in the switch, end it with a break, and return the value of the variable in the end.
(On the ... third? hand... you can always refactor a switch into its own method... I doubt it will have an effect on performance, and it wouldn't surprise me if modern compilers could even recognize it as something that could be inlined...)
Keep the breaks - you're less likely to run into trouble if/when you edit the code later if the breaks are already in place.
Having said that, it's considered by many (including me) to be bad practice to return from the middle of a function. Ideally a function should have one entry point and one exit point.
What do you think? Is it fine to remove them? Or would you keep them for increased "correctness"?
It is fine to remove them. Using return is exactly the scenario where break should not be used.
I would say remove them and define a default: branch.
Wouldn't it be better to have an array with
arr[0] = "blah"
arr[1] = "foo"
arr[2] = "bar"
and do return arr[something];?
If it's about the practice in general, you should keep the break statements in the switch. In the event that you don't need return statements in the future, it lessens the chance it will fall through to the next case.
For "correctness", single entry, single exit blocks are a good idea. At least they were when I did my computer science degree. So I would probably declare a variable, assign to it in the switch and return once at the end of the function
Interesting. The consensus from most of these answers seems to be that the redundant break statement is unnecessary clutter. On the other hand, I read the break statement in a switch as the 'closing' of a case. case blocks that don't end in a break tend to jump out at me as potential fall though bugs.
I know that that's not how it is when there's a return instead of a break, but that's how my eyes 'read' the case blocks in a switch, so I personally would prefer that each case be paired with a break. But many compilers do complain about the break after a return being superfluous/unreachable, and apparently I seem to be in the minority anyway.
So get rid of the break following a return.
NB: all of this is ignoring whether violating the single entry/exit rule is a good idea or not. As far as that goes, I have an opinion that unfortunately changes depending on the circumstances...
I say remove them. If your code is so unreadable that you need to stick breaks in there 'to be on the safe side', you should reconsider your coding style :)
Also I've always prefered not to mix breaks and returns in the switch statement, but rather stick with one of them.
I personally tend to lose the breaks. Possibly one source of this habit is from programming window procedures for Windows apps:
LRESULT WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
return sizeHandler (...);
case WM_DESTROY:
return destroyHandler (...);
...
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
I personally find this approach a lot simpler, succinct and flexible than declaring a return variable set by each handler, then returning it at the end. Given this approach, the breaks are redundant and therefore should go - they serve no useful purpose (syntactically or IMO visually) and only bloat the code.
I think the *break*s are there for a purpose. It is to keep the 'ideology' of programming alive. If we are to just 'program' our code without logical coherence perhaps it would be readable to you now, but try tomorrow. Try explaining it to your boss. Try running it on Windows 3030.
Bleah, the idea is very simple:
Switch ( Algorithm )
{
case 1:
{
Call_911;
Jump;
}**break**;
case 2:
{
Call Samantha_28;
Forget;
}**break**;
case 3:
{
Call it_a_day;
}**break**;
Return thinkAboutIt?1:return 0;
void Samantha_28(int oBed)
{
LONG way_from_right;
SHORT Forget_is_my_job;
LONG JMP_is_for_assembly;
LONG assembly_I_work_for_cops;
BOOL allOfTheAbove;
int Elligence_says_anyways_thinkAboutIt_**break**_if_we_code_like_this_we_d_be_monkeys;
}
// Sometimes Programming is supposed to convey the meaning and the essence of the task at hand. It is // there to serve a purpose and to keep it alive. While you are not looking, your program is doing // its thing. Do you trust it?
// This is how you can...
// ----------
// **Break**; Please, take a **Break**;
/* Just a minor question though. How much coffee have you had while reading the above? I.T. Breaks the system sometimes */
Exit code at one point. That provides better readability to code. Adding return statements (Multiple exits) in between will make debugging difficult .
Simply define variable and return it at last of the switch statement and we can also remove default statement by setting variable= default value.
Ex:
switch(someVariable)
{
case 'a':
return a;
break;
case 'b':
return b;
break;
default:
return c;
}
solution:
$result = c; //for default value
switch(someVariable)
{
case 'a':
$result = a;
break;
case 'b':
$result = b;
break;
}
return $result; //simply return $result
This will lead to reduce your return statement.