在C++或C中,foo(void)和foo()之间有区别吗?

283

考虑这两个函数定义:

void foo() { }

void foo(void) { }

这两者之间有任何区别吗?如果没有,为什么要有 void 参数呢?只是为了美观吗?


对于 C 语言,Q/A 在这里 - Antti Haapala -- Слава Україні
4个回答

358
C中:
  • void foo() 表示 "一个名为 foo 的函数,参数数量和类型未指定"
  • void foo(void) 表示 "一个名为 foo 的函数,不带参数"
C++中:
  • void foo() 表示 "一个名为 foo 的函数,不带参数"
  • void foo(void) 表示 "一个名为 foo 的函数,不带参数"
因此,通过编写 foo(void),我们可以在两种语言中实现相同的解释,并使头文件多语言化(尽管通常我们需要在C++编译时将它们包装在 extern "C" 中才能真正实现跨语言)。

13
如果 C++ 要求使用 void,那么它就可以避免“最令人烦恼的解析”问题。 - Adrian McCarthy
7
没错,但是C++中有很多其他糟糕的解析方式,所以抱怨其中任何一种都没有真正的意义。 - DrPizza
16
最初的 C 语言版本没有允许指定函数参数的数量,因此 void foo() 是声明函数的唯一语法。引入参数签名后,C 委员会必须将无参数与旧语法区分开来,并引入 void foo(void) 语法。为了保持兼容性,C++ 也采用了这种语法。@James Kanze 在最近的一个问题中发表了一个有趣的小知识,现在转载来避免遗失。 - Matthieu M.
3
您能否举一个在C C90及其后版本中,使用void foo()而不是void foo(void)会产生实际差异的例子?也就是说,我多年来一直使用没有void的版本,但并没有发现问题,我是否有所遗漏?可以给您一个例子:在声明函数时,如果使用void foo(),表示该函数接受任意数量和类型的参数。而如果使用void foo(void),则表示该函数不接受任何参数。因此,如果您在调用函数时使用了错误的参数,将会产生编译错误或运行时错误。建议您始终使用void foo(void)以确保代码的可读性和稳定性。 - chacham15
12
函数 void foo() { if ( rand() ) foo(5); } 可以编译和运行(如果你非常幸运的话),但会导致未定义的行为。而如果将函数声明改为 void foo(void),尽管函数体相同,却会导致编译错误。需要注意的是,本段话涉及技术性语言和概念,可能需要进一步解释才能完全理解。 - M.M
显示剩余13条评论

42

我知道你的问题与C++有关,但对于C语言的答案可以在K&R的第72-73页找到:

Furthermore, if a function declaration does not include arguments, as in

double atof();

that too is taken to mean that nothing is to be assumed about the arguments of atof; all parameter checking is turned off. This special meaning of the empty argument list is intended to permit older C programs to compile with new compilers. But it's a bad idea to use it with new programs. If the function takes arguments, declare them; if it takes no arguments, use void.


1
但问题是关于定义,此时相关的C规则是:在函数定义中作为函数声明符一部分的空参数列表指定该函数没有参数。 - jinawee

10

C++11 N3337标准草案

没有区别。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

附录C“兼容性”C.1.7条款8:声明符说:

8.3.5 Change: In C ++ , a function declared with an empty parameter list takes no arguments. In C, an empty parameter list means that the number and type of the function arguments are unknown.

Example:

int f();
// means int f(void) in C ++
// int f( unknown ) in C

Rationale: This is to avoid erroneous function calls (i.e., function calls with the wrong number or type of arguments).

Effect on original feature: Change to semantics of well-defined feature. This feature was marked as “obsolescent” in C.

8.5.3 函数中提到:

4. 参数声明确定了在调用函数时可以指定的参数及其处理方式。如果参数声明为空,函数不带任何参数。空参数列表(void)等同于空参数列表。

C99

如C++11所述,int f()未对参数进行说明,已经过时。

它可能会导致代码工作或UB。

详细解释请参见我在Stack Overflow上对C99标准的解释。


语法高亮在“means int”附近关闭了。你能修复一下吗?例如,在注释中关闭或者像这里中的“void”更像。 - Peter Mortensen

3
在 C 语言中,你需要在空函数引用中使用 void,以便编译器有一个原型,并且该原型“没有参数”。而在 C++ 中,你不需要告诉编译器你有一个原型,因为你不能省略原型。

2
“原型”指的是参数列表声明和返回类型。我这么说是因为一开始“原型”让我感到困惑,不知道你的意思是什么。 - Zan Lynx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接