[英]Extremely simple C program won't compile in gcc compiler
我有以下程序
main()
{
char a,b;
printf("will i get the job:");
scanf("%c",&a);
printf("%c",a);
printf("We did it");
}
我将文件另存为Hope.c
当我尝试使用gcc编译器编译上面的代码时,会出现以下错误:
Hope.c:In function 'main':
Hope.c:4:2:warning:incompatible implicit declaration of built-in function 'printf' [enabled by default]
Hope.c:5:2:warning:incompatible implicit declaration of built-in function scanf[enabled by default]
当我使用printf()
或scanf()
,即使在简单的“ Hello world”程序中,编译器也会出现此错误。
我的代码有问题吗,还是编译器有问题?
您在顶部缺少#include <stdio.h>
。 请注意,这些只是警告,不是错误。 您的程序仍应按原样编译。
另外,为了很好地度量,您应该将返回类型和参数写出到main()并在最后返回一个值。
#include <stdio.h>
int main(void)
{
char a,b;
printf("will i get the job:");
scanf("%c",&a);
printf("%c",a);
printf("We did it");
return 0;
}
当您调用不熟悉的函数时,请查看手册页并包括其中提到的标题 。 在您的情况下为#include <stdio.h>
。
这确实非常重要,例如,我经历过printf( "%s", func( ) )
引起分段错误,尽管func()
返回了一个有效的空终止字符串,但是没有原型声明func()
的返回类型为char *
(进行了一些研究,我们发现只有64位指针的最后四个字节已传递给printf()
)
是的,代码有问题。 您在使用函数printf
和scanf
而不声明它们。
通常要做的是使用编译器附带的声明(因为它们是正确的)。
#include <stdio.h>
C.89 / C.90允许隐式声明函数。 警告消息通知您尚未为scanf
和printf
提供显式声明。 如前所述,您可以通过在程序的开头添加#include <stdio.h>
来更正此问题。 通过不这样做,程序的行为是不确定的。
由于scanf()
和printf()
具有隐式声明,因此将它们视为其原型被视为:
extern int scanf ();
extern int printf ();
这些声明指出, scanf()
和printf()
接受数量未知的as,返回和int
。 但是,这种声明仍然假定这些函数将采用固定数量的参数。 这与他们的真实原型不兼容,在真实原型中,他们采用了可变数量的参数:
extern int scanf (const char *, ...);
extern int printf (const char *, ...);
您的C编译器显然了解这些函数的真实原型,因为它将这些函数视为“内置”,这意味着在编译为调用这些函数的源代码时,它可以生成特殊情况的代码。 由于隐式声明与其对原型的内置知识不匹配,因此它会生成警告。
不具备此“内置知识”的编译器可能不会生成警告。 然后,它将生成代码来调用scanf()
和printf()
,就像它们接受了固定数量的参数一样。 该错误然后可能会在运行时发生,因为采用可变数量参数的函数的调用约定可能与采用固定数量参数的函数的调用约定不同。
所有这些都在C.89§3.3.2.2中进行了描述。
如果函数调用中带括号的参数列表之前的表达式仅由标识符组成,并且该标识符没有可见的声明,则隐式声明该标识符,就像在包含函数调用的最里面的块中完全声明该声明一样。
extern int identifier();
出现了。
...
如果表示被调用函数的表达式的类型不包括原型,则对每个参数执行整数提升,并将具有float类型的参数提升为双精度。 ...如果函数的定义类型包含原型,并且升级后的参数类型与参数类型不兼容,或者原型以省略号(“, ...
”)结尾,行为是不确定的。
请注意,C.99删除了隐式函数声明的余量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.