c 编译器是否可以将 'if-elseif' 块转换为 'switch' 块以优化代码?

Is it possible for a c compiler to transform an 'if-elseif' bloc into a 'switch' bloc to optimize the code?

c 编译器是否可以将 'if-elseif' 块转换为 'switch' 块以优化代码?

以下代码:

if ( a == 1 ) {
  bloc1
} else if ( a == 2 ) {
  bloc2
} else if ( ... ) {
....
} else if ( a == n ) {
  bloc n
}

在编译过程中转换为:

switch(a) {
  case 1:
    bloc1
    break;

  case 2:
    bloc2
    break;
  ...
  case n:
    blocn
    break;
}

如果每次都可行,那么 'if...elseif' 块对 'switch' 块的优势是否再次出现?

case 中,您从未听说过 "as-if" 规则:here it is。也就是说,允许编译器迁移ifswitch在某些场合, 是的。

switch 应尽可能使用;它为编译器提供了有关所解析数据类型的更多信息,并使其能够构建类似于哈希表的东西。
当不能使用switch时,应使用if。就是这么简单。

只要不以任何方式改变程序意图,c 编译器就可以进行任何它喜欢的优化。

注意到 switch 只能出现在整数类型上,在您的情况下转换为 switch 似乎是最佳选择。相信你的优化者会在适当的时候做出这样的转变。您可以随时检查输出程序集以进行验证。

编译器将 C 代码翻译成机器代码。在汇编程序级别,没有 ifelseswitch 这样的东西。只有条件分支和非条件分支。

所以,不,编译器永远不会像你建议的那样做任何事情,因为可以用 switch 替换的 if-else 已经产生相同的机器代码,无论哪个你写的。中间没有"convert C to C"步。

出于这个原因,switch 是一种晦涩的语言功能,因为它在理论上是完全多余的。 switch 是否会导致代码的可读性更高或更差,这是主观的。它可以根据具体情况执行。


特例:

当所有 case 标签都是相邻的整数常量时,编译器可以对 switch 语句进行常见的优化,即用一个替换整个 switch函数指针数组。然后它可以简单地使用 switch 条件作为数组索引来确定调用哪个函数。无需比较。这是一个相当激进的优化,因为它删除了许多比较,从而加快了代码速度,改进了分支预测等。

如果你有一个 if - else if 链,同样的优化是可能的,就像这样:

if(n==0)
{ }
else if(n==1)
{ }
else if(n==2)
{ }
...

这也可以优化成一个函数指针数组,就像写成 switch.