1

这是我的代码:

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

现在因为 C 可以隐式声明一个函数,这个程序将正确编译(就像它使用 gcc 一样)。
但我的问题是,第一个printf声明不是返回一个带有 1 个类型参数的 intchar *吗?
这使得第二printf个错误。
然而程序编译没有错误,只是警告(gcc)。为什么 ?

4

4 回答 4

3

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

引文C11,前言

第二版的主要变化包括:

— 删除隐式函数声明

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

  • 返回一个int
  • 接受任意数量和类型的参数。

所以,只要函数声明和定义不冲突(比如,返回类型不匹配),你就不会得到任何错误。然而,一个严格符合的编译器必须产生一个诊断。

于 2017-09-25T13:14:54.920 回答
2

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

于 2017-09-25T13:13:45.393 回答
0

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

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

于 2017-09-25T13:17:12.137 回答
0

不幸的是,即使没有使用头文件,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 );
      ^

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

于 2017-09-25T13:35:20.367 回答