C中同一函数的多个隐式声明

Multiple implicit declaration of same function in C

这是我的代码:

int main(){
    printf("Hi");
    int i=10;
    printf("Hi %d",i);
    return 0;
}

现在,由于 C 可以隐式声明一个函数,因此该程序将正确编译(与 gcc 一样)。
但我的问题是,不是第一个 printf 声明为 return 一个带有 1 个 char * 类型参数的 int 吗?
这使得第二个 printf 成为错误。
然而程序编译没有错误,只是警告(gcc)。为什么?

在您的例子中,printf 被隐式定义为 int printf(...),而不是 int printf(char *),因此当您使用不同的参数调用它时,编译器不会检测到任何错误。

严格来说,隐式声明是违反标准的。它已从标准中删除。

引用C11,前言

Major changes in the second edition included:

— remove implicit function declaration

也就是说,在早期版本的 C 中,对于被认为是隐式声明的函数(即,在编译器了解函数原型之前使用) 应该

  • return一个int
  • 接受任何数量和类型的参数。

因此,只要函数声明和定义不冲突(例如,return 类型不匹配),您就不会收到任何错误。但是,严格符合标准的编译器必须产生诊断。

您的代码不可移植 C,因为您缺少必要的 #include,它为 printf 引入了函数原型:在 C99 中删除了任何类型的隐式声明。

如果您想编写不可移植的 C,那么您能做的最好的事情就是查阅您的编译器文档。在这种情况下,您友好的编译器似乎默认为 int printf(...).

不幸的是,gcc 有一些内置的 printf 概念,即使没有使用头文件。

unsigned int fun ( unsigned int x )
{
    printf("%s\n");
    printf("%u\n",x);
    more_fun("%s\n");
    more_fun("%u\n",x);
    return(x+1);
}

so.c: In function ‘fun’:
so.c:5:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
     printf("%s\n");
     ^
so.c:5:5: warning: incompatible implicit declaration of built-in function ‘printf’
so.c:5:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
so.c:5:12: warning: format ‘%s’ expects a matching ‘char *’ argument [-Wformat=]
     printf("%s\n");
            ^
so.c:7:5: warning: implicit declaration of function ‘more_fun’ [-Wimplicit-function-declaration]
     more_fun("%s\n");
     ^

幸运的是,如果我们自己制作,它至少会忘记一点。

void printf(char *, unsigned int );
void more_fun(char *, unsigned int );
unsigned int fun ( unsigned int x )
{
    printf("%s\n");
    printf("%u\n",x);
    more_fun("%s\n");
    more_fun("%u\n",x);
    return(x+1);
}

so.c:3:6: warning: conflicting types for built-in function ‘printf’
 void printf(char *, unsigned int );
      ^
so.c: In function ‘fun’:
so.c:7:5: error: too few arguments to function ‘printf’
     printf("%s\n");
     ^
so.c:3:6: note: declared here
 void printf(char *, unsigned int );
      ^
so.c:9:5: error: too few arguments to function ‘more_fun’
     more_fun("%s\n");
     ^
so.c:4:6: note: declared here
 void more_fun(char *, unsigned int );
      ^

但是我们正在谈论一种编译器,一种编译器不涵盖它你必须尝试many/all。标准与否,编译器仍然可以注意到您更改函数的使用并让您知道,该编译器选择不这样做。这里的错误不是编译器没有注意到函数从一个未声明的实例到另一个实例的使用方式不同,而是没有声明,然后它确实注意到了人们希望的差异。