简体   繁体   English

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

[英]Multiple implicit declaration of same function in C

Here's my code: 这是我的代码:

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

Now as C can implicitly declare a function this program will compile correctly (As it does with gcc). 现在,由于C可以隐式声明一个函数,因此该程序将正确编译(与gcc一样)。
But my question is, wasn't the 1st printf declared to return an int with 1 parameter of type char * ? 但是我的问题是,不是第一个printf声明返回具有char *类型的1参数的char *吗?
That makes the 2nd printf an error. 这会使第二个printf出错。
Yet the program compiles with no errors, just warnings (gcc). 但是该程序编译时没有错误,只是警告(gcc)。 Why ? 为什么呢

Strictly speaking, implicit declaration is standard violation. 严格来说,隐式声明是标准违规行为。 It is removed from the standard. 它已从标准中删除。

Quoting C11 , Foreword 引用C11 ,前言

Major changes in the second edition included: 第二版的主要变化包括:

— remove implicit function declaration —删除隐式函数声明

That said, in earlier version of C, for a function which is considered declared implicitly (ie, used before the compiler has knowledge about the function prototype) was supposed to 这就是说,在C的早期版本中,这被认为是隐式声明的函数(即编译器之前采用了对函数的原型知识) 本来是要

  • return an int 返回一个int
  • accepts any number and type of parameter. 接受任何数量和类型的参数。

So, as long as the function declaration and the definition does not collide (say, return type mismatch), you'll not get any error. 因此,只要函数声明和定义不冲突(例如,返回类型不匹配),就不会出现任何错误。 However, a strictly conforming compiler MUST produce a diagnostic. 但是,严格符合要求的编译器必须产生诊断信息。

在您的情况下, printf被隐式定义为int printf(...) ,而不是int printf(char *) ,因此,当您使用其他参数调用编译器时,编译器不会检测到错误。

Your code is not portable C since you're missing the requisite #include which brings in the function prototype for printf : any sort of implicit declaration was removed in C99. 您的代码不是可移植的C,因为您缺少必不可少的#include ,后者为printf了函数原型:C99中删除了任何类型的隐式声明。

If you want to write non-portable C, then the best thing you can do is to consult your compiler documentation. 如果要编写不可移植的C,那么最好的办法是查阅编译器文档。 In this instance it looks like your friendly compiler is defaulting to int printf(...) . 在这种情况下,您友好的编译器似乎默认为int printf(...)

gcc unfortunately has some built in notion of printf even though a header file has not been used. 不幸的是,即使没有使用头文件,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");
     ^

fortunately if we make our own it does forget at least a little. 幸运的是,如果我们自己制造,它至少会遗忘一点。

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 );
      ^

but we are talking about one compiler, one compiler does not cover it you have to try many/all. 但是我们谈论的是一个编译器,一个编译器不能解决这个问题,您必须尝试很多/全部。 Standard or not a compiler could still notice your changing the use of the function and let you know about it, this compiler chooses not to. 无论标准编译器与否,编译器仍会注意到您对该函数的使用进行了更改,并让您知道,该编译器选择不这样做。 The error here is not that the compiler didnt notice the function being used differently from one undeclared instance to another but that there was no declaration, and then it does notice the difference as one would hope. 这里的错误不是因为编译器没有注意到该函数在一个未声明的实例和另一个未声明的实例之间的用法不同,而是没有声明,然后它确实注意到了所希望的差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM