问题描述
要真正符合标准,C 中的所有函数(main 除外)都必须有一个原型,即使它们只在同一翻译单元中定义之后使用?
To be truly standards-compliant, must all functions in C (except for main) have a prototype, even if they are only used after their definition in the same translation unit?
推荐答案
这取决于您所说的真正符合标准"是什么意思.然而,简短的回答是最好确保所有函数在使用前都有一个范围内的原型".
It depends on what you mean by 'truly standards compliant'. However, the short answer is "it is a good idea to ensure that all functions have a prototype in scope before being used".
一个更合格的答案指出,如果函数接受可变参数(特别是 printf()
函数系列),那么原型必须在范围内才能严格符合标准.这适用于 C89(来自 ANSI)和 C90(来自 ISO;除了节编号外与 C89 相同).但是,除了 'varargs' 函数,返回 int
的函数不必声明,返回 int
以外的函数的函数确实需要一个声明来显示返回类型,但不需要参数列表的原型.
A more qualified answer notes that if the function accepts variable arguments (notably the printf()
family of functions), then a prototype must be in scope to be strictly standards compliant. This is true of C89 (from ANSI) and C90 (from ISO; the same as C89 except for the section numbering). Other than 'varargs' functions, though, functions which return an int
do not have to be declared, and functions that return something other than an int
do need a declaration that shows the return type but do not need the prototype for the argument list.
但是,请注意,如果函数采用在没有原型的情况下受正常提升"影响的参数(例如,采用 char
或 short
- 两者都被转换为 int
;更严重的,也许是一个接受 float
而不是 double
的函数,然后需要一个原型.标准对此很松懈,以允许旧的 C 代码在符合标准的编译器下编译;编写较旧的代码时不会担心确保在使用前声明函数 - 根据定义,较旧的代码不使用原型,因为在出现标准之前,原型无法在 C 中使用.
Note, however, that if the function takes arguments that are subject to 'normal promotions' in the absence of prototypes (for example, a function that takes a char
or short
- both of which are converted to int
; more seriously, perhaps, a function that takes a float
instead of a double
), then a prototype is needed. The standard was lax about this to allow old C code to compile under standard conformant compilers; older code was not written to worry about ensuring that functions were declared before use - and by definition, older code did not use prototypes since they did not become available in C until there was a standard.
C99 不允许 'implicit int'...这意味着像 'static a;
'(默认情况下为 int
)这样的奇怪情况和隐式函数声明.在 ISO/IEC 9899:1999 的前言中提到了这些(以及大约 50 个其他主要变化),将该标准与以前的版本进行比较:
C99 disallows 'implicit int'...that means both oddball cases like 'static a;
' (an int
by default) and also implicit function declarations. These are mentioned (along with about 50 other major changes) in the foreword to ISO/IEC 9899:1999,which compares that standard to the previous versions:
- 去除隐含的
int
…… - 删除隐式函数声明
在 ISO/IEC 9899:1990 的 §6.3.2.2 函数调用中指出:
In ISO/IEC 9899:1990, §6.3.2.2 Function calls stated:
如果函数调用中括号参数列表之前的表达式包含唯一的标识符,如果没有对该标识符可见的声明,则该标识符是隐式的就像在包含函数调用的最里面的块中声明一样:
extern int identifier();
出现了.
即声明为具有块作用域的标识符与类型函数有外部链接,没有参数信息并返回一个 int
.如果实际上它没有定义为具有类型功能返回 int
,"行为未定义.
That is, an identifier with block scope declared to have external linkage with type function without parameter information and returning an int
. If in fact it is not defined as having type "function returning int
," the behavior is undefined.
1999 标准中缺少此段落.我还没有(还)跟踪在 C90 中允许 static a;
和在 C99 中不允许它(需要 static int a;
)的措辞变化.
This paragraph is missing in the 1999 standard. I've not (yet) tracked the change in verbiage that allows static a;
in C90 and disallows it (requiring static int a;
) in C99.
请注意,如果函数是静态的,则可以在使用之前对其进行定义,而无需在其之前进行声明.如果在定义非静态函数之前没有声明(-Wmissing-prototypes
),则 GCC 会被说服.
Note that if a function is static, it may be defined before it is used, and need not be preceded by a declaration. GCC can be persuaded to witter if a non-static function is defined without a declaration preceding it (-Wmissing-prototypes
).
这篇关于C89、C90 或 C99 中的所有函数都需要原型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!