我目前正在重构/整理C ++项目中使用的一些旧C代码,并定期查看以下函数:
int f(void)
我倾向于写作:
int f()
是否有任何理由不在整个代码库中用()替换(void)以提高一致性,或者两者之间是否存在我不知道的细微差别?更具体地说,如果C ++中的虚拟成员函数被描述为:
virtual int f(void)
,派生类包含成员函数:
int f()
这是一个有效的覆盖?另外,基于几乎相同的签名,我是否可能遇到任何链接器问题?
答案 0 :(得分:96)
在C中,声明int f(void)
表示返回int的函数,该函数不带参数。声明int f()
表示返回int的函数,它接受任意数量的参数。因此,如果你有一个在C中没有参数的函数,那么前者就是正确的原型。
在C ++中,我认为{@ 1}}已被弃用,而int f(void)
是首选,因为它特别指的是不带参数的函数。
答案 1 :(得分:21)
根据我的经验,使用int f()
添加到Chris的答案是不好的做法,因为你失去了编译器将函数声明与其定义进行比较的能力,以确保正确调用它。 / p>
例如,以下代码符合标准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
的其他定义)。
答案 2 :(得分:17)
上面的答案是完全正确的,但是我链接到David Tribble的优秀页面,因为它在这个和许多其他问题上给出great explanation。
亮点:
C区分功能 使用空参数列表声明 和一个用a声明的函数 参数列表仅包含 无效。前者是无原型的 函数取一个未指定的数字 论证,而后者是 原型功能没有 参数。
另一方面,C ++没有 区分两者 声明,并考虑他们两个 意思是一个没有的功能 参数。对于预期的代码 编译为C或C ++,最好的 解决这个问题的方法是永远 声明函数不带参数 使用明确的void原型。
空函数原型是一个 C99中已弃用的功能(因为它们 在C89)。
编辑:在查看标准之后,或许值得注意的是,在C ++中,func(void)语法不已被弃用,但它通常被认为更多是C风格的习语。我认为我遇到的大多数C ++程序员更喜欢空参数列表。
编辑2:添加C ++标准的引用,第8.3.5节,第2段:
“如果参数声明子句为空,则该函数不带参数。参数列表(void)等效于空参数列表。除了这种特殊情况,void不应该是参数类型(尽管类型不同)源自void,例如void *,can)。“
没有提及任何一种形式都被弃用。再次感谢Tribble先生的优秀网站,指出我正确的标准部分。
答案 3 :(得分:2)
tl; dr:使用void
。
考虑到C ++中的向后兼容性,以及下面确定的含糊不清,我断言我们一直回到KnR和ANSI C以获得确定的答案:
int getline(void);
int copy(void)
由于getline和copy的专用版本没有参数, 逻辑会建议他们的原型在文件的开头 应为
getline()
和copy()
。但为了兼容性 旧的C程序标准将空列表作为旧式 声明,并关闭所有参数列表检查;这个单词void
必须用于显式空列表。 [Kernighan&amp; Richie,C编程语言,1988,Pgs 32-33]
和..
空参数列表的特殊含义是允许的 使用新编译器编译的旧C程序。但这是一个坏主意 将它与新程序一起使用。如果函数接受参数,则声明 他们;如果没有参数,请使用void [同上,Pg。 73]
编辑:在这里单独讨论其余部分: Does specifying the use of void in the declaration of a function that takes no arguments address The Most Vexing Parse?
答案 4 :(得分:1)
<强> C11 N1570 standard draft 强>
不推荐使用 void f()
,建议void f(void)
:
6.11.6函数声明符:
1 使用带有空括号的函数声明符(不是prototype-format参数 类型声明者)是一个过时的功能。
简介:
2某些功能已过时,这意味着它们可能会被考虑使用 退出本国际标准的未来修订版。他们被保留是因为 它们的广泛使用,但它们在新的实现中的使用(用于实现 不建议使用新的程序(用于语言[6.11]或库功能[7.31])。
详细讨论:https://stackoverflow.com/a/36292431/895245
不推荐使用void f(void)
和void f()
。
void f(void)
存在与C的兼容性。附件C“兼容性”C.1.7第8条:声明者:
8.3.5更改:在C ++中,使用空参数列表声明的函数不带参数。在C中,一个空的 参数列表表示函数参数的数量和类型是未知的。
由于C中不推荐使用void f()
而建议使用void f(void)
,因此只要C ++想要保持兼容性,就会存在void f(void)
。
void f(void)
和void f()
在C ++中是相同的。因此,如果您关心编写在C和C ++下编译的代码,那么void f(void)
只会更有意义,这可能是不值得的。
答案 5 :(得分:-1)
在C ++中,int f(void)
确实是一个已弃用的声明,它与int f()
完全相同。它是相同的签名。此上下文中的void
与例如{1}一样重要。空白。这也意味着它们受一个定义规则(它们不会重载)和Derived::f(void)
覆盖Base::f()
的约束。
不要混淆像f(const void)
这样的东西。这种古怪意味着什么并不是很多共识。