int main ()
{
hello();
return 0;
}
int hello()
{
printf("\n hello world");
return 0;
}
根据C规则,main()
下面定义的每个函数都必须在main()
之上声明,但为什么它是int
作为返回类型的函数的异常?
如果将hello()
的返回类型更改为其他任何内容(void,char *等)
它会抛出错误的声明。为什么int
返回类型没有错误或警告?
答案 0 :(得分:5)
这是C的旧功能,现在官方不受支持。
在早些时候(在C99之前,如果我没有错误),如果函数的返回类型丢失,或者函数缺少正向声明,则函数为假设返回int
并接受任意数量的参数。您对函数的实际定义也与假设相匹配,因此链接器也不会抱怨。
您的编译器仍支持该旧功能(主要是因为保持了与使用旧标准编写的程序的向后兼容性),因此您成功编译并链接了该程序。
仅供参考,在最新的C标准C11
中,正式提及
- 删除隐式函数声明
所以,根据严格的检查,强制转发声明一个函数(或者,在它的使用之前定义,以便编译器不必假设任何东西)。
答案 1 :(得分:0)
由于其发展和发展的历史,C保留了其他语言中不赞成的东西。这是因为如果C编译器没有保持向后兼容性,那么很多旧的C代码都会崩溃。
这个想法是新的C代码应该使用新的样式和约定。但是,C编译器会尽力保持与旧源代码和约定的兼容性。
由于C编译器供应商不愿意破坏现有的旧源代码,您将看到编译的C源代码似乎违反了新C标准的规则。
我自己使用旧源代码,当我使用Visual Studio 2015时,警告的数量令人难以置信,因为重复标记了相同的问题。结果是对于这大量代码,我关闭了某些警告。
你提到的函数声明只是一个。还有新的安全类型的字符串函数和I / O函数与旧样式没有额外的长度参数。
答案 2 :(得分:0)
C中有一个约定,声明没有返回类型的函数默认返回类型为int。 此外,变量的默认类型说明符也是int。例如,Borland C ++ Builder 5.0支持这样的声明
const VALUE = 10;
答案 3 :(得分:0)
自C99以来,在使用之前需要声明;一旦实现为未能包含此类声明而发出诊断,它可以继续处理源文件,或者根据需要继续处理。
在C的早期,在void
添加到语言之前,int
是迄今为止最常见的返回类型。在每个调用站点都会推断出参数类型,因此编译器不需要知道除返回类型之外的任何函数。此外,可以处理大于32K的文件的文本编辑器被认为是奢侈品,并且能够跳过预处理器可以减少编译时间的几秒钟。将这些事实放在一起,并且能够省略大多数函数的声明,增加了可以包含在每个源文件中的有用代码的数量。