请解释一下这个片段:
#include <stdio.h>
int puts(const char *str) {
fputs("Hello world!\n", stdout);
}
int main() {
printf("Goodbye\n");
}
输出:Hello world!
返回13
答案 0 :(得分:10)
它是特定于编译器的。您使用GCC获得此行为。以下是一些细节。
因为您#include <stdio.h>
(实际上是因为您处于托管环境中)puts
是C99标准的版本,重新定义它是undefined behavior
GCC编译器进行了一些优化,可将某些printf
转换为更快 puts
的序列。这是合法的,因为您已经包含<stdio.h>
(并且C99标准定义了printf
在这种情况下应该做什么; GCC通过__builtin_printf
作为中间步骤
如果使用-ffreestanding
进行编译,则不会发现这一点。
你的问题非常接近this one;所以this answer也是相关的。
答案 1 :(得分:7)
我用gcc x.c -S -o-
编译了程序。它给了我
[...]
main:
.LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
movl $.LC1, (%esp)
call puts
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE1:
因此,printf
调用确实在GCC中被puts
替换,因为它们具有相同的语义。
答案 2 :(得分:6)
我的猜测是编译器将对printf()
的调用更改为对puts()
的调用,因为由于没有格式化,不需要printf()
。此字符串也由换行符终止,换行符puts()
。编译器没有看到你的库函数的可怕重载,所以它被愚弄了#34;。