什么是`-S`的优化级别切换到GCC

时间:2014-08-04 12:00:54

标签: gcc optimization assembly

在这个question中,我遇到gcc myfile.c -S生成的汇编代码优于gcc myfile.c -O0但比gcc myfile.c -O1更差的情况。

  

在-O0,生成两个循环。在-O1,两个循环都被优化了。 (感谢@Raymond Chen的提醒。引用他的评论)(使用-S只是优化一个循环

我在互联网上搜索只发现:

-S(引自Overall options

  

在编译阶段之后停止;不要组装。对于指定的每个非汇编器输入文件,输出采用汇编程序代码文件的形式。

     

默认情况下,源文件的汇编程序文件名是通过将后缀“.c”,“。i”等替换为“.s”来生成的。

     

忽略不需要编译的输入文件。

所以我的问题是:

  • 编译文件时-S选项的优化级别是什么? (-O0.5?)

  • 为什么不使用-O0-O1 ...(或者它是一个错误?)

修改:您可以使用此site来帮助您重现问题。代码在我提到的question中。 (如果只使用-S编译器选项(或没有编译器选项),则可以获得一个循环省略。)

第1步:

打开此site并在Code Eidtor中复制以下代码。

 #include <stdio.h>
 int main (int argc, char *argv[]) {

   unsigned int j = 10;

   for (; j > -1; --j) {    
      printf("%u", j);
   }
 }

第2步:

选择g++ 4.8作为编译器。 编译器选项为空。(或-S)

第3步:

你得到了第一种情况。现在,将j > -1更改为j >= -1,您可以看到第二个。

2 个答案:

答案 0 :(得分:1)

-S没有优化。另一方面,-O0会停用所有优化功能,即使是默认优化

因此,您看到的效果是您已启用&#34;启用&#34;如果仅使用-S,则为默认优化。

使用-S和各种-O选项来查看对汇编代码的影响。

编辑我从大约2.6(1994年)开始使用GCC。我很确定我记得在某些版本中,编译器会执行默认优化,您可以使用-O0禁用它来调试编译器(即gcc ...崩溃,gcc -O0 ...不会崩溃 - &gt;恭喜,你发现了一个错误。)

但这似乎并非如此。我获得了-S-O0的相同汇编程序输出,但没有给出任何一个。因此,无论选择哪个优化级别,似乎总是应用简单优化(如if(0){}注释掉代码块)。

因此,我要说的是上面的原始陈述:

  

在-O0,生成两个循环。在-O1,两个循环都被优化了。 (感谢@Raymond Chen的提醒。引用他的评论)(使用-S只是优化一个循环)

开头不正确(至少对于GCC 4.8.2)。唯一的另一种选择是OP(4.8)使用的GCC版本在启用/禁用优化器选项时存在错误。

答案 1 :(得分:1)

通过上一次编辑,现在可以清楚地知道你在做什么了,所以:

对于1.案例,j > -1

这种情况永远不会发生。 j是无符号整数,-1转换为无符号值将对应于设置了所有位的值。这与UINT_MAX相同,j永远不会大于j >= -1。所以gcc消除了循环,因为它的条件总是假的

对于2.案例,j

这可能发生。如上所述,(unsigned int)-1肯定会成为-S或UINT_MAX。循环没有消除。

  

编译文件时-S选项的优化级别是什么? (-O0.5?)

使用-O标志控制优化级别。 -O不会影响优化。如果没有给出-O0标志,则默认优化为{{1}}(无优化)