在这个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编译器选项(或没有编译器选项),则可以获得一个循环省略。)
打开此site并在Code Eidtor中复制以下代码。
#include <stdio.h>
int main (int argc, char *argv[]) {
unsigned int j = 10;
for (; j > -1; --j) {
printf("%u", j);
}
}
选择g++ 4.8
作为编译器。 编译器选项为空。(或-S)
你得到了第一种情况。现在,将j > -1
更改为j >= -1
,您可以看到第二个。
答案 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}}(无优化)