首页 > 解决方案 > 编译器优化开关的方式是否与长 if-then-else 链不同?

问题描述

假设我在编译时有 N 个不同的整数值,从 V_1 到 V_N。考虑以下结构:

const int x = foo();
switch(x) {
case V_1: { /* commands for V_1 which don't change x */ } break;
case V_2: { /* commands for V_1 which don't change x */ } break;
/* ... */
case V_N: { /* commands for V_1 which don't change x */ } break;
}

相对

const int x = foo();
if      (x == V_1) { /* commands for V_1 which don't change x */ }
else if (x == V_2) { /* commands for V_2 which don't change x */ }
else ...
else if (x == V_N) { /* commands for V_N which don't change x */ }

现代 C++ 编译器是否以不同的方式处理这些?也就是说,他们是否对这些代码结构应用了不同的潜在优化?或者他们是否将它们“规范化”为相同的,然后决定优化(例如是否形成跳转表)?

笔记:

标签: c++switch-statementg++compiler-optimizationclang++

解决方案


Ironically, that is exactly the test I did just a couple of days back for most recent compilers. As it happened, with latest compilers, clang produces the same assembly for switch and if - for small number of cases (below 5) it produces a bunch of direct conditional jumps, while for 5 or more cases it does an indirect table jump.

On the other hand, gcc treats those differently: it converts switch to indirect table jump, while a series of if statements remain a series of conditional direct jumps.

It is also worth noting, that if switch case has "holes" in it (i.e. possible values for control variable which are not covered by case label), it can be still converted into series of conditional direct jumps or indirect table jump, but I wasn't able to figure out the exact formula.

Here is some play code: https://gcc.godbolt.org/z/Lll1Kd


推荐阅读