有人可以解释这种行为吗?只需2行代码

use*_*628 9 c

请解释这个片段:

#include <stdio.h>

int puts(const char *str) {
    fputs("Hello world!\n", stdout);
}

int main() {
    printf("Goodbye\n");
}
Run Code Online (Sandbox Code Playgroud)

输出:Hello world!返回13

Bas*_*tch 10

它是特定于编译器的.你得到GCC的这种行为.这是一些细节.

  • 因为你#include <stdio.h>(实际上是因为你在托管环境中)puts是C99标准的,并且重新定义它是未定义的行为

  • GCC编译器有一些优化可以将一些转换printf更快 的序列puts.这是合法的,因为你已经包含了<stdio.h>(并且C99标准定义了printf在那种情况下应该做什么; GCC __builtin_printf作为中间步骤)

如果你与你一起编译-ffreestanding将不会观察到.

你的问题非常接近这个问题; 所以这个答案也很重要.


glg*_*lgl 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:
Run Code Online (Sandbox Code Playgroud)

实际上,printf调用puts在GCC中被替换,因为它们具有相同的语义.


unw*_*ind 6

我的猜测是,编译器改变了呼叫printf()到一个电话puts(),因为没有必要printf(),由于没有格式.该字符串也由换行符终止puts().编译器没有看到你的库函数的可怕重载,所以它被"愚弄"了.