[C]"default" bei "switch/case" immer notwendig?

Herakles

Profifragensteller
Moin!

Hat ein

Code:
default:
(...)
break;

irgendeinen Sinn, wenn dieser Codeteil nie erreicht werden kann?

Nehmen wir sowas an:

Code:
if( (p!=1) && (p!=2) ) return -1;
switch(p) {
    case 1:
        printf("toll\n");
    break;
    case 2:
        printf("hurra\n");
    break;
    default:
    break;
}

Der default-Teil wird nie erreicht. Sollte er dennoch im Code zu finden sein?

Viele Grüße
Herakles, der Profi-Frager
 

-Nuke-

Well-Known Member
Nö. Es ist bei dem Code egal ob default jetzt so da steht oder nicht. Maximal eine Verständlichkeit, aka:

default da: Man erwartet andere Werte, tut dann aber nichts

default nicht da: Man erwartet keine anderen Werte
 

dettus

Bicycle User
das default geht in die richtung von
Code:
for (;;) {} // loop forever
printf("yay! forever came!!\n");

aber spass beiseite: es ist guter programmierstil den mit einzubauen, vielleicht aendert sich ja im laufe der zeit etwas.
gute compiler optimieren den weg. im schlimmsten fall wird dein programm ein paar bytes groesser und ein paar takte langsamer.
 

h^2

hat ne Keule +1
Langsamer sollte das Programm dadurch auf keinen Fall werden. Wenn in jedem Fall ein break vor dem default aufgerufen wird, ist wird das was danach kommt egal, da können auch noch beliebige andere Bdingungen auftauchen. Bei einem
if (( a==b) || (c==d))
wird (c==d) auch nie geprüft, wenn (a==b) immer stimmt.
 

döna

Well-Known Member
Es ist halt mehr so ne Maintainance-Sache.
Normalerweise steht nach dem Default sowas wie assert(0);
in der Release-Version wird dieses dann vom Compiler wegoptimiert
und wenn du mal was erweiterst, siehst du, ob und wo du den Case
vergessen hast.
 

dettus

Bicycle User
NOOBS ;)

mehr oder weniger code hat durchaus auswirkungen auf die ausfuehrungszeit :belehren:
weil der dann u.u. den instruction-cache anders beeinflusst.

das wird aber erst dann interessant wenn ihr an embedded systemen rumschraubt die echtzeitfaehig sein muessen. von daher: macht euch keine sorgen.
und das a==b||c==d wird auch nur dann nicht ausgewertet wenn das ausfuehrende system eine lazy evaluation kann.
"system" schliesst hierbei den compiler mit ein.

ich habs mal eben probiert, gcc 4.1.2 auf einem amd64 linux kanns zum beispiel.
 

Tron

Well-Known Member
und das a==b||c==d wird auch nur dann nicht ausgewertet wenn das ausfuehrende system eine lazy evaluation kann.
"system" schliesst hierbei den compiler mit ein.

ich habs mal eben probiert, gcc 4.1.2 auf einem amd64 linux kanns zum beispiel.
Das Verhalten ist keine Lust-und-Laune-Sache, die C-Norm schreibt dies vor:
ISO/IEC 9899:1999 (E) §6.5.14:4 schrieb:
[...] If the first operand compares unequal to 0, the second operand is not evaluated.

Im Allgemeinen ist es unentscheidbar, ob ein bestimmter Punkt in einem Programm erreichbar ist oder nicht. Es bedarf schon einiger Analyse, um auch nur das Eingangsbeispiel zu bewältigen.
Es gibt aber einen Grund, default bewusst wegzulassen: Aufzählungen.
Code:
enum E { A, B, C } x;
...
switch (x) {
case A: ... return;
case B: ... return;
}
abort();
Lässt man default weg und fügt einen weiteren Eintrag in die Aufzählung ein (im Beispiel das C), dann wird ein heutiger Übersetzer eine Warnung ausgeben, dass man den Fall C nicht in dem switch behandelt.
 

oenone

Well-Known Member
Manchmal gibt es auch Code-Richtlinien von der Firma, für die man arbeitet. Da kann es festgeschrieben sein, dass es auf jeden Fall ein "default" geben muss.
 

dettus

Bicycle User
Das Verhalten ist keine Lust-und-Laune-Sache, die C-Norm schreibt dies vor:
ah! man lernt halt nie aus.
cool! dann werde ich das demnaechste oefter verwenden!!! danke!!!!!!!!!!!

aber abgesehen davon war meine aussage jetzt auch nicht c-spezifisch gemeint. lassen wir das, ist ja doch ein [c] topic.
 
Oben