次のsquareの実装は、連鎖ifステートメントに期待するような一連のcmp / jeステートメントを生成します。
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;
}
}
そして、以下は返されるデータテーブルを生成します:
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;
}
}
なぜgccは一番上のものを一番下のものに最適化できないのですか?
参照用の逆アセンブリ:https ://godbolt.org/z/UP_igi
編集:興味深いことに、MSVCはスイッチケースのデータテーブルの代わりにジャンプテーブルを生成します。そして驚くべきことに、clangはそれらを同じ結果に最適化します。
return
sを無視します。ケースにはがないbreaks
ため、スイッチにも特定の実行順序があります。if / elseチェーンはすべてのブランチでリターンを持ち、この場合のセマンティクスは同等です。最適化は不可能ではありません。反例として、iccはどの関数も最適化しません。