在现代C和C ++中不推荐使用f(void)

时间:2009-01-06 12:34:40

标签: c++ c refactoring void

我目前正在重构/整理C ++项目中使用的一些旧C代码,并定期查看以下函数:

int f(void)

我倾向于写作:

int f()

是否有任何理由不在整个代码库中用()替换(void)以提高一致性,或者两者之间是否存在我不知道的细微差别?更具体地说,如果C ++中的虚拟成员函数被描述为:

virtual int f(void)

,派生类包含成员函数:

int f()

这是一个有效的覆盖?另外,基于几乎相同的签名,我是否可能遇到任何链接器问题?

6 个答案:

答案 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

C++11 N3337 standard draft

不推荐使用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)只会更有意义,这可能是不值得的。

详细讨论:https://stackoverflow.com/a/36835303/895245

答案 5 :(得分:-1)

在C ++中,int f(void)确实是一个已弃用的声明,它与int f()完全相同。它相同的签名。此上下文中的void与例如{1}一样重要。空白。这也意味着它们受一个定义规则(它们不会重载)和Derived::f(void)覆盖Base::f()的约束。

不要混淆像f(const void)这样的东西。这种古怪意味着什么并不是很多共识。