【发布时间】:2017-06-07 07:58:16
【问题描述】:
这是我的测试代码:
#include<stdio.h>
static inline void foo(int a){
printf("%x\n", a);
}
int main(void){
foo(0x1234);
return 0;
}
我认为 GCC 应该意识到 a 是一个字面整数,并优化为这样的代码:
puts("1234");
但我得到了以下汇编代码:
│0x8048341 <main+17> push $0x1234
│0x8048346 <main+22> push $0x80484e0
│0x804834b <main+27> push $0x1
│0x804834d <main+29> call 0x8048310 <__printf_chk@plt>
我的项目中有很多这样的代码,因为我一直相信 GCC 会为我优化,甚至在某些可以简单地使用 'write()' 的情况下,我坚持使用printf,因为我认为我会从它的缓冲机制中受益。
现在我感到很遗憾,因为解析格式字符串的开销会扼杀我所拥有的任何收益。我项目中的这些代码非常底层,可能会导致性能瓶颈。
【问题讨论】:
-
依靠编译器为你神奇地优化事物通常是一种无望的做法。
-
我不认为编译器曾经可以优化库调用。您可以链接一个库,其中
printf()具有编译器在编译阶段无法知道的副作用。 -
@FelixPalmen 不,编译器可以,因为
printf()是由 C 标准定义的。 -
@Stargateur 实际上,为
%x传递int可能是明确定义的,因为va_arg允许混合签名(C99 中的7.15.1.1)。 GCC 和 Clang 似乎同意这种解释,因为即使使用-Wformat=2,它们也不会发出警告。 -
@M.M GCC 仍然需要根据格式确定要输出的正确字符串。实现这种优化当然是可能的,但也许它被认为不值得维护
printf的副本的麻烦。也许几年后我们会得到它? :)
标签: c gcc assembly compiler-optimization