我有一个 C 程序,我在其中定义和使用我自己的printf()函数。但是,仅输出第一个printfie 。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;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Hello World 1
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么
根据ISO C11标准的\xc2\xa77.1.3,该标识符printf被保留供标准库使用。即使您不包含头文件,这也适用,因为标识符具有外部链接。因此,就 ISO C 标准而言,您的程序正在调用未定义的行为,这意味着任何事情都可能发生,包括您所描述的行为。
但是,如果您问为什么编译器 gcc 会这样做,那么答案会更复杂一些,因为编译器 gcc 有它自己的规则:
\n在gcc中,该函数printf是一个内置函数。这允许编译器优化该行
printf("Hello World 1\\n");\nRun Code Online (Sandbox Code Playgroud)\n到:
\nputs("Hello World 1");\nRun Code Online (Sandbox Code Playgroud)\n它不会对printf具有多个参数的调用执行此优化,因此该行
printf("Hello World %d\\n", 2);\nRun Code Online (Sandbox Code Playgroud)\n没有得到优化puts。
因此,您发布的代码实际上被编译为以下内容:
\nint printf (const char *__restrict __format, ...);\n\nint printf (const char *__restrict __format, ...) {}\n\nint main() {\n puts("Hello World 1");\n printf("Hello World %d\\n", 2);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n如果你想阻止gcc优化对调用printf的调用puts,那么你可以使用-fno-builtin命令行选项来阻止gcc将函数识别为内置函数,或者-fno-builtin-printf只阻止printf函数被识别为内置函数。请注意,即使您使用这些选项,您仍然可以使用前缀显式调用这些函数的内置版本__builtin_,例如__builtin_printf.