C语言 为什么只有第一个printf输出到终端?

fcy6dtqo  于 2023-03-28  发布在  其他
关注(0)|答案(1)|浏览(199)

我有一个C程序,我定义并使用了自己的printf()函数,但是只输出了第一个printf,即printf("Hello World 1\n");,为什么呢?

int printf(const char *__restrict __format, ...);

int printf(const char *__restrict __format, ...) {}

int main() {
    printf("Hello World 1\n");
    printf("Hello World %d\n", 2);
    return 0;
}

输出为:

Hello World 1

但我不明白为什么

qv7cva1a

qv7cva1a1#

根据ISO C11标准的§7.1.3,标识符printf是保留给标准库使用的。即使你没有包含头文件,这也适用,因为标识符有external linkage。因此,就ISO C标准而言,你的程序正在调用未定义的行为,这意味着任何事情都可能发生,包括你描述的行为。
然而,如果你问为什么编译器gcc会这样做,那么答案就有点复杂了,因为编译器gcc有自己的规则:
在gcc中,函数printf是一个内置函数,它允许编译器优化代码行

printf("Hello World 1\n");

致:

puts("Hello World 1");

它不会对具有多个参数的printf调用执行此优化,因此这行代码

printf("Hello World %d\n", 2);

不会优化为puts
因此,您发布的代码有效地编译为以下内容:

int printf (const char *__restrict __format, ...);

int printf (const char *__restrict __format, ...) {}

int main() {
    puts("Hello World 1");
    printf("Hello World %d\n", 2);
    return 0;
}

如果您想阻止gcc将printf调用优化为puts调用,则可以使用-fno-builtin命令行选项来阻止gcc将函数识别为内置函数,或使用-fno-builtin-printf命令行选项来仅阻止将printf函数识别为内置函数。请注意,即使使用这些选项,你仍然可以使用__builtin_前缀显式调用这些函数的内置版本,例如__builtin_printf

相关问题