编译器会优化转义内循环吗?

BCS*_*BCS 7 c++ compiler-construction optimization

我的代码看起来像这样(显示完成的所有用法):

bool done = false;
for(int i = 0; i < big; i++)
{
  ...
  for(int j = 0; j < wow; j++)
  {
    ...
    if(foo(i,j))
    {
       done = true;
       break;
    }
    ...
  }
  if(done) break;
  ...
}
Run Code Online (Sandbox Code Playgroud)

将任何编译器转换为此:

for(int i = 0; i < big; i++)
{
  ...
  for(int j = 0; j < wow; j++)
  {
    ...
    if(foo(i,j))
      goto __done; // same as a labeled break if we had it
    ...
  }
  ...
}
__done:;
Run Code Online (Sandbox Code Playgroud)

注意:虽然我最感兴趣的是如果if(done)break;被绕过并作为死代码被删除,我也对它是否感兴趣并且done完全被删除.

Cog*_*eel 14

显然这取决于编译器.当您不确定时,最好的办法是查看编译器的汇编输出(所有流行的编译器都有一个开关).即使您不熟悉汇编,也至少可以将调试版本与优化版本进行比较.

话虽这么说,这是少数几个goto不是坏主意的情况之一.随意使用它来打破内循环.

编辑

刚刚在VS2010中尝试了以下内容,它确实优化了外部条件:

bool done = false;
for(int i = 0; i < 10; i++)
{
    for(int j = 0; j < 10; j++)
    {
        if(i == 7 && j == 3)
        {
            done = true;
            break;
        }
    }
    if(done) break;
}
return 0;
Run Code Online (Sandbox Code Playgroud)

  • +1实用主义.很多人都忽略了这样一个事实,即当他们让代码难以理解时,从函数和其他类似东西中获取,断点,多个返回点都是不好的._明智地使用这些东西很好. (16认同)

Cub*_*bbi 7

GNU编译器就是这样做的,从优化级别-O1开始(我在x86_64上使用gcc 4.5.1)

call    _Z3fooii  // al = foo(i,j)
testb   %al, %al
jne .L14
...
Run Code Online (Sandbox Code Playgroud)

其中.L14是放置__done的标签:

一个更好的问题可能是:哪个现代编译器执行此优化?