为什么我能够用C语言重写printf?

sad*_*t_1 4 c

考虑下一段代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

int printf(const char *format, ...)
{
    va_list args;

    return 1;
}

int main()
{
    printf("Hello there");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

事实上,printf什么也没有打印。这意味着,编译器“更喜欢”这个函数而不是<stdio.h>. 但C不允许函数重写,根据我的理解,它应该抛出冲突错误的错误。

谁能解释这种行为?

n. *_* m. 5

C 标准规定(7.1.3 保留标识符):

  • 以下任何子条款(包括未来的库方向)中具有外部链接的所有标识符和 errno 始终保留用作具有外部链接的标识符。
  • 以下任何子条款(包括未来的库方向)中列出的每个具有文件范围的标识符都被保留用作宏名称,并且如果包含其任何关联的标头,则可用作同一名称空间中具有文件范围的标识符。
  • 如果程序在保留标识符的上下文中声明或定义标识符(7.1.4 允许的除外),或者将保留标识符定义为宏名称,则行为为 undefined

因此,当<stdio.h>包含时,printf被保留为普通标识符的名称空间中具有文件范围的标识符。此外,即使不包含在内printf,也始终保留为具有外部链接的标识符。<stdio.h>

7.1.4 使用库函数不允许定义具有保留名称的函数。

在大多数实现中,此类定义将默默地替换库函数,但标准不保证任何内容。