更新时间:2023-12-01 07:49:57
这是一个老式函数声明.
本声明:
void foo();
声明 foo
是一个返回 void
的函数,它接受一个未指定但固定数量和类型的参数.这并不意味着带有任意参数的调用是有效的;这意味着编译器无法使用错误数量或类型的参数诊断错误调用.
declares that foo
is a function returning void
that takes an unspecified but fixed number and type(s) of arguments. It doesn't mean that calls with arbitrary arguments are valid; it means that the compiler can't diagnose incorrect calls with the wrong number or type of arguments.
某处,也许在另一个翻译单元(源文件)中,必须有函数的定义,也许:
Somewhere, perhaps in another translation unit (source file), there has to be a definition of the function, perhaps:
void foo(x, y)
long x;
double *y;
{
/* ... */
}
这意味着对 foo
的任何调用不会传递两个 long
和 double*
类型的参数> 无效,并且具有未定义的行为.
This means that any call to foo
that doesn't pass two arguments of type long
and double*
is invalid, and has undefined behavior.
在 1989 ANSI C 标准之前,这些是该语言中唯一可用的函数声明和定义类型,编写正确函数调用的负担完全由程序员承担.ANSI C 添加了原型,即指定函数参数类型的函数声明,允许在编译时检查函数调用.(这个特性是从早期的 C++ 中借来的.)上面的现代等价物是:
Prior to the 1989 ANSI C standard, these were the only kind of function declaration and definition available in the language, and the burden of writing correct function calls was entirely on the programmer. ANSI C added prototypes, function declarations that specify the types of a function's parameters, which allow compile-time checking of function calls. (This feature was borrowed from early C++.) The modern equivalent of the above would be:
void foo(long x, double *y);
/* ... */
void foo(long x, double *y) {
/* ... */
}
旧式(非原型)声明和定义仍然合法,但它们正式过时,这意味着,原则上,它们可以从语言的未来版本中删除-- 尽管它们仍然存在于 2011 年标准中,但我不知道这是否会真正发生.
Old-style (non-prototype) declarations and definitions are still legal, but they're officially obsolescent, which means that, in principle, they could be removed from a future version of the language -- though since they're still around in the 2011 standard I don't know that that will ever actually happen.
没有充分的理由在现代 C 代码中使用旧式函数声明和定义.(我已经看到在某些极端情况下使用它们的论据,但我发现它们没有说服力.)
There is no good reason to use old-style function declarations and definitions in modern C code. (I've seen arguments for using them in some corner cases, but I find them unconvincing.)
C 还支持 variadic 函数,如 printf
,它接受任意数量的参数,但这是一个独特的特性.可变参数函数必须用原型声明,其中包括尾随的 , ...
.(调用没有可见原型的可变参数函数并不违法,但它具有未定义的行为.)该函数本身使用
中定义的宏来处理其参数.与旧式函数声明一样,没有编译时检查对应于 , ...
的参数(尽管一些编译器可能会检查一些调用;例如 gcc 会警告 , ...
中的参数code>printf 调用与格式字符串不一致).
C also supports variadic functions like printf
, which do take an arbitrary number of arguments, but that's a distinct feature. A variadic function must be declared with a prototype, which includes a trailing , ...
. (Calling a variadic function with no visible prototype isn't illegal, but it has undefined behavior.) The function itself uses macros defined in <stdarg.h>
to process its parameters. As with old-style function declarations, there is no compile-time checking for arguments corresponding to the , ...
(though some compilers may check some calls; for example gcc warns if the arguments in a printf
call are inconsistent with the format string).