在现代的C和C ++中已经弃用了f(void)
我目前正在重构/整理C ++项目中使用的一些旧C代码,并定期查看以下函数:
int f(void)
我倾向于这样写:
int f()
为了提高一致性,是否有任何理由不在整个代码库中用()replace(void),还是两者之间有细微的差别,我不知道? 更具体地说,如果C ++中的虚拟成员函数被描述为:
virtual int f(void)
而派生类包含一个成员函数:
int f()
这是一个有效的覆盖? 此外,我可能会遇到基于几乎相同的签名的任何链接器问题?
在C中,声明int f(void)
表示一个返回int的函数,不带任何参数。 声明int f()
意味着一个返回int的函数,它接受任意数量的参数。 因此,如果你有一个在C中没有参数的函数,前者是正确的原型。
在C ++中,我相信int f(void)
是不推荐使用的, int f()
是首选,因为它具体指的是不带参数的函数。
为了增加Chris的回答,根据我的经验,使用int f()
在C中是不好的做法,因为你失去了编译器将函数的声明与其定义进行比较的能力,以确保它将被正确调用。
例如,下面的代码是符合标准的C:
#include <stdio.h> void foo(); void bar(void) { foo(); } void foo(int a) { printf("%d\n", a); }
但是这会导致未定义的行为,因为a
没有被传递给foo
。
在C ++中,有两个版本的foo
:一个不接受参数,一个接受int
。 因此, bar
调用未定义的版本,这将导致链接器错误(假设没有任何其他的foo
定义)。
上面的答案是非常正确的,但是我把大卫·特莱布尔的优秀页面连接起来,因为它对这个和其他许多问题给出了很好的解释 。
亮点:
C区分用空参数列表声明的函数和用仅由void构成的参数列表声明的函数。 前者是一个没有原型的函数,其参数数量不详,而后者是一个没有参数的原型函数。
另一方面,C ++没有区分这两个声明,并认为它们都是不带参数的函数。
对于打算编译为C或C ++的代码,解决此问题的最佳方法是始终声明不带参数的函数,并显式声明void原型。
空函数原型在C99中是一个不推荐的function(就像它们在C89中一样)。
编辑:在看标准之后,可能值得注意的是func(void)语法在C ++中不被弃用,但是它通常被认为更多的是C风格的习惯用法。 我认为大多数我所运行的C ++程序员更喜欢空的参数列表。
编辑2:从C ++标准,第8.3.5节,第2段添加一个引用:
如果参数声明子句是空的,函数不带任何参数,参数列表(void)等价于空的参数列表,除了这个特殊情况,void不应该是参数types(尽pipetypes从void ,如void *,可以)。“
没有提及任何forms都被弃用。 再次感谢Tribble先生的优秀网站,指出我标准的正确部分。
tl; dr:使用void
。
考虑到C ++中的向后兼容性,以及下面指出的歧义位,我断言我们一直回到KnR和ANSI C作为一个确定的答案:
int getline(void); int copy(void)
由于getline和copy的特定版本没有参数,因此逻辑会build议它们在文件开头的原型应该是
getline()
和copy()
。 但为了与旧的C程序兼容,标准将一个空列表作为旧式的声明,并closures所有的参数列表检查;void
一词必须用于明确的空列表。 [Kernighan&Richie,C编程语言,1988,页32-33]
和..
空参数列表的特殊含义是为了允许较早的C程序使用新的编译器进行编译。 但是用新程序来使用它是一个坏主意。 如果函数需要参数,则声明它们; 如果没有参数,则使用void [ibid,Pg。 73]
编辑:其余的打破了这里的一个单独的讨论: 是否在函数的声明中指定void的使用,没有参数地址最烦人的parsing?
C11 N1570标准草案
void f()
被弃用, void f(void)
推荐:
6.11.6函数声明符 :
1具有空括号的函数声明符(不是原型格式参数types声明符)的使用是过时的特性。
介绍 :
2某些function已经过时,这意味着在本标准的未来修订中可能会考虑撤销。 由于它们的广泛使用,它们被保留下来,但是它们在新的实现(用于实现function)或新的程序(用于语言[6.11]或库特征[7.31])中的使用是不鼓励的。
详细讨论: https : //stackoverflow.com/a/36292431/895245
C ++ 11 N3337标准草案
void f(void)
和void f()
都不推荐使用。
void f(void)
与C兼容。 附录C“兼容性”C.1.7第8条:声明符 :
8.3.5更改:在C ++中,用空参数列表声明的函数不带任何参数。 在C中,一个空的参数列表意味着函数参数的数量和types是未知的。
由于void f()
在C中被弃用,而void f(void)
推荐,所以只要C ++想保持兼容性, void f(void)
就会存在。
void f(void)
和void f()
在C ++中是相同的。 所以如果你关心编写在C和C ++下编译的代码,那么更长的void f(void)
才有意义,这可能是不值得的。
详细的讨论: https : //stackoverflow.com/a/36835303/895245
在C ++中,int f(void)实际上是一个不赞同的声明,它与int f()的100%相等。 这是相同的签名。 在这种情况下,空白和空白一样重要。 这也意味着他们受制于一个定义规则(他们不重载)和Derived :: f(void)重写Base :: f()
尽pipe如此,不要像f(const void)这样的东西混淆。 这种怪异的含义并不是很一致。