所以GCC和Clang都很聪明,可以优化printf("%s\n", "foo") to puts("foo") (GCC,嘎吱声)。这一切都很好。
但是当我通过编译器资源管理器运行这个函数时
#include <stdio.h>
void foo(void) {
printf("%s", "foo");
}GCC和Clang都没有将printf("%s", "foo")优化为fputs("foo", stdout),我认为这应该是完全相同的(因为fputs没有像puts那样把换行符放在printf上),而且速度更快。
GCC 11.1 (链接):
.LC0:
.string "foo"
.LC1:
.string "%s"
foo:
mov esi, OFFSET FLAT:.LC0
mov edi, OFFSET FLAT:.LC1
xor eax, eax
jmp printfx86-64 Clang 12.0.0 (链接):
foo: # @foo
mov edi, offset .L.str
mov esi, offset .L.str.1
xor eax, eax
jmp printf # TAILCALL
.L.str:
.asciz "%s"
.L.str.1:
.asciz "foo"是否有任何特定的理由不优化fputs,或者编译器不够聪明?
发布于 2021-05-01 10:52:13
有些非常具体的情况是经过优化的,比如您展示的情况,但这是非常肤浅的,如果您在您的格式字符串中添加了一些内容,甚至是一个空格,它就是printf。
我想没有什么可以阻止更广泛的优化,我的推测是,由于性能收益并不大,进一步增加更多的特殊情况被认为是不值得的。
在我的推测中,缺乏fputs优化将属于不值得的范畴。
这位老gcc 优化文件为这些优化提供了一些启示,我怀疑今天是否会有很大的不同。
具体地说:
2.3
%s\n格式字符串%s\n行4679-4687的printf调用被转换为puts()调用。 printf("%s\n","hello world");//转换为put(“hello world");2.8字符串不以\n结尾 如果字符串没有以\n行4721-4739结尾,则不进行优化。2.9以\n结尾的字符串 以printf行4721-4739结尾的简单格式字符串的\n调用被转换为puts()调用。 printf("hello world\n");//转换为put(“hello world");
https://stackoverflow.com/questions/67344987
复制相似问题