Die folgende Implementierung von square erzeugt eine Reihe von cmp / je-Anweisungen, wie ich es von einer verketteten if-Anweisung erwarten würde:
int square(int num) {
if (num == 0){
return 0;
} else if (num == 1){
return 1;
} else if (num == 2){
return 4;
} else if (num == 3){
return 9;
} else if (num == 4){
return 16;
} else if (num == 5){
return 25;
} else if (num == 6){
return 36;
} else if (num == 7){
return 49;
} else {
return num * num;
}
}
Und das Folgende erzeugt eine Datentabelle für die Rückgabe:
int square_2(int num) {
switch (num){
case 0: return 0;
case 1: return 1;
case 2: return 4;
case 3: return 9;
case 4: return 16;
case 5: return 25;
case 6: return 36;
case 7: return 49;
default: return num * num;
}
}
Warum kann gcc den oberen in den unteren nicht optimieren?
Demontage als Referenz: https://godbolt.org/z/UP_igi
BEARBEITEN: Interessanterweise generiert MSVC eine Sprungtabelle anstelle einer Datentabelle für den Switch-Fall. Und überraschenderweise optimiert Clang sie auf das gleiche Ergebnis.
return
s; Die Fälle haben keine breaks
, daher hat der Switch auch eine bestimmte Ausführungsreihenfolge. Die if / else-Kette hat in jedem Zweig Rückgaben, die Semantik ist in diesem Fall äquivalent. Die Optimierung ist nicht unmöglich . Als Gegenbeispiel optimiert icc keine der Funktionen.