Consider the following switch
statement:
switch( value )
{
case 1:
return 1;
default:
value++;
// fall-through
case 2:
ret
It's valid and very useful in some cases.
Consider the following code:
switch(poll(fds, 1, 1000000)){
default:
// here goes the normal case : some events occured
break;
case 0:
// here goes the timeout case
break;
case -1:
// some error occurred, you have to check errno
}
The point is that the above code is more readable and efficient than cascaded if
. You could put default
at the end, but it is pointless as it will focus your attention on error cases instead of normal cases (which here is the default
case).
Actually, it's not such a good example, in poll
you know how many events may occur at most. My real point is that there are cases with a defined set of input values where there are 'exceptions' and normal cases. If it's better to put exceptions or normal cases at front is a matter of choice.
In software field I think of another very usual case: recursions with some terminal values. If you can express it using a switch, default
will be the usual value that contains recursive call and distinguished elements (individual cases) the terminal values. There is usually no need to focus on terminal values.
Another reason is that the order of the cases may change the compiled code behavior, and that matters for performances. Most compilers will generate compiled assembly code in the same order as the code appears in the switch. That makes the first case very different from the others: all cases except the first one will involve a jump and that will empty processor pipelines. You may understand it like branch predictor defaulting to running the first appearing case in the switch. If a case if much more common that the others then you have very good reasons to put it as the first case.
Reading comments it's the specific reason why the original poster asked that question after reading Intel compiler Branch Loop reorganisation about code optimisation.
Then it will become some arbitration between code readability and code performance. Probably better to put a comment to explain to future reader why a case appears first.
One scenario where I would consider it appropriate to have a 'default' located somewhere other than the end of a case statement is in a state machine where an invalid state should reset the machine and proceed as though it were the initial state. For example:
switch(widget_state) { default: /* Fell off the rails--reset and continue */ widget_state = WIDGET_START; /* Fall through */ case WIDGET_START: ... break; case WIDGET_WHATEVER: ... break; }
an alternative arrangement, if an invalid state should not reset the machine but should be readily identifiable as an invalid state:
switch(widget_state) { case WIDGET_IDLE: widget_ready = 0; widget_hardware_off(); break; case WIDGET_START: ... break; case WIDGET_WHATEVER: ... break; default: widget_state = WIDGET_INVALID_STATE; /* Fall through */ case WIDGET_INVALID_STATE: widget_ready = 0; widget_hardware_off(); ... do whatever else is necessary to establish a "safe" condition }
Code elsewhere may then check for (widget_state == WIDGET_INVALID_STATE) and provide whatever error-reporting or state-reset behavior seems appropriate. For example, the status-bar code could show an error icon, and the "start widget" menu option which is disabled in most non-idle states could be enabled for WIDGET_INVALID_STATE as well as WIDGET_IDLE.
The default
condition can be anyplace within the switch that a case clause can exist. It is not required to be the last clause. I have seen code that put the default as the first clause. The case 2:
gets executed normally, even though the default clause is above it.
As a test, I put the sample code in a function, called test(int value){}
and ran:
printf("0=%d\n", test(0));
printf("1=%d\n", test(1));
printf("2=%d\n", test(2));
printf("3=%d\n", test(3));
printf("4=%d\n", test(4));
The output is:
0=2
1=1
2=4
3=8
4=10
The case statements and the default statement can occur in any order in the switch statement. The default clause is an optional clause that is matched if none of the constants in the case statements can be matched.
Good Example :-
switch(5) {
case 1:
echo "1";
break;
case 2:
default:
echo "2, default";
break;
case 3;
echo "3";
break;
}
Outputs '2,default'
very useful if you want your cases to be presented in a logical order in the code (as in, not saying case 1, case 3, case 2/default) and your cases are very long so you do not want to repeat the entire case code at the bottom for the default