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

时间:2014-10-23 09:10:24

标签: c

请解释一下这个片段:

#include <stdio.h>

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

int main() {
    printf("Goodbye\n");
}

输出:Hello world!返回13

3 个答案:

答案 0 :(得分:10)

它是特定于编译器的。您使用GCC获得此行为。以下是一些细节。

  • 因为您#include <stdio.h>(实际上是因为您处于托管环境中)puts是C99标准的版本,重新定义它是undefined behavior

    < / LI>
  • 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;。

相关问题