A implementação a seguir do square produz uma série de instruções cmp / je, como eu esperaria de uma instrução if encadeada:
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;
}
}
E o seguinte produz uma tabela de dados para retorno:
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;
}
}
Por que o gcc não consegue otimizar o de cima para o de baixo?
Desmontagem para referência: https://godbolt.org/z/UP_igi
EDIT: curiosamente, o MSVC gera uma tabela de salto em vez de uma tabela de dados para o caso do comutador. E, surpreendentemente, o clang os otimiza para o mesmo resultado.
return
; os casos não têm breaks
, portanto, o switch também possui uma ordem específica de execução. A cadeia if / else tem retornos em todos os ramos, a semântica neste caso é equivalente. A otimização não é impossível . Como um contra-exemplo, o icc não otimiza nenhuma das funções.