L'implémentation suivante de square produit une série d'instructions cmp / je comme j'attendrais d'une instruction if chaînée:
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;
}
}
Et ce qui suit produit une table de données pour le retour:
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;
}
}
Pourquoi gcc est-il incapable d'optimiser celui du haut dans celui du bas?
Démontage pour référence: https://godbolt.org/z/UP_igi
EDIT: intéressant, MSVC génère une table de saut au lieu d'une table de données pour le boîtier de commutation. Et étonnamment, clang les optimise pour le même résultat.
return
s; les cas n'ont pas breaks
, donc le commutateur a également un ordre d'exécution spécifique. La chaîne if / else a des retours dans chaque branche, la sémantique dans ce cas est équivalente. L'optimisation n'est pas impossible . Comme contre-exemple icc n'optimise aucune des fonctions.