这取决于你所说的"真正符合标准"是什么意思.然而,简短的答案是"在使用之前,确保所有函数都有一个范围内的原型是个好主意".
一个更合格的答案指出,如果函数接受变量参数(特别是printf()
系列函数),则原型必须在严格符合标准的范围内.C89(来自ANSI)和C90(来自ISO;除章节编号外与C89相同)也是如此.但是,除了"varargs"函数之外,返回int
的函数不必声明,返回int
以外的值的函数需要显示返回类型的声明,但不需要参数列表的原型.
但是,请注意,如果函数采用的参数在没有原型的情况下会受到"正常提升"的影响(例如,采用char
或short
的函数——两者都转换为int
;更严重的是,可能采用float
而不是double
的函数),则需要一个原型.该标准在这方面很宽松,允许旧的C代码在符合标准的编译器下编译;编写旧代码并不是为了确保函数在使用前声明——根据定义,旧代码并没有使用原型,因为直到有了标准,原型才在C中可用.
C99不允许‘IMPLICIT INT’.这意味着既有像‘static a;
’(默认情况下是int
)这样的奇怪情况,也有隐式函数声明.在ISO/IEC 9899:1999的前言中提到了这些(以及大约50个其他主要变化),
它将该标准与以前的版本进行了比较:
- 删除隐式
int
- 删除隐式函数声明
在ISO/IEC 9899:1990中,§6.3.2.2 Function calls规定:
如果函数调用中括号参数列表前面的表达式包含
extern int identifier();
出现了38
38也就是说,一个具有块作用域的标识符被声明为具有类型函数的外部链接,而没有
1999年标准中缺少该段.我还没有(至今)跟踪C90中允许static a;
而C99中不允许它(需要static int a;
)的措辞变化.
请注意,如果函数是静态的,则可以在使用之前对其进行定义,并且不需要在其前面加声明.如果一个非静态函数的定义之前没有声明(-Wmissing-prototypes
),那么GCC可以说服witter.