我目前正在重构/整理 C++ 项目中使用的一些旧 C 代码,并且经常看到诸如以下的函数:
int f(void)
我倾向于将其写为:
int f()
有什么理由不在整个代码库中用 () 替换 (void)为了提高一致性,或者两者之间是否存在我不知道的细微差别?
更具体地说,如果 C++ 中的虚拟成员函数被描述为:
virtual int f(void)
并且派生类包含成员函数:
int f()
这是有效的重写吗? 此外,我是否可能会遇到基于几乎相同签名的链接器问题?
I'm currently refactoring/tidying up some old C code used in a C++ project, and regularly see functions such as:
int f(void)
which I would tend to write as:
int f()
Is there any reason not to replace (void) with () throughout the codebase in order to improve consistency, or is there a subtle difference between the two that I am unaware of?
More specifically, if a virtual member function in C++ is described as:
virtual int f(void)
and a derived class includes a member function:
int f()
is this a valid override? Additionally, am I likely to encounter any linker problems based on almost identical signatures?
发布评论
评论(6)
在 C 语言中,声明 int f(void) 表示返回 int 且不带参数的函数。 声明
int f()
表示返回 int 且接受任意数量参数的函数。 因此,如果 C 中有一个不带参数的函数,则前者是正确的原型。在 C++ 中,我认为
int f(void)
已被弃用,而int f()
是首选,因为它具体表示不带参数的函数。In C, the declaration
int f(void)
means a function returning int that takes no parameters. The declarationint f()
means a function returning int that takes any number of parameters. Thus, if you have a function that takes no parameters in C, the former is the correct prototype.In C++, I believe
int f(void)
is deprecated, andint f()
is preferred, as it specifically means a function that takes no parameters.要添加到 Chris 的答案,请使用 <根据我的经验,code>int f() 在 C 中是不好的做法,因为编译器失去了将函数的声明与其定义进行比较的能力,以确保正确调用它。
例如,以下代码是符合标准的 C:
但它会导致未定义的行为,因为
a
未传递给foo
。在 C++ 中,有两个版本的
foo
:一种不带参数,另一种带int
。 因此bar
最终会调用未定义的版本,这将导致链接器错误(假设任何地方都没有foo
的其他定义)。To add to Chris's answer, using
int f()
is bad practice in C, in my experience, since you lose the compiler's ability to compare the function's declaration to its definition, to ensure that it will be called correctly.For example, the following code is standards-compliant C:
But it results in undefined behavior, since
a
was not passed tofoo
.In C++, there are two versions of
foo
: one that takes no arguments and one that takes anint
. Sobar
winds up calling the undefined version, which would result in a linker error (assuming there are no other definitions offoo
anywhere).前面的答案非常正确,但我链接到 David Tribble 的优秀页面,因为它给出了 关于这个问题和许多其他问题的很好的解释。
亮点:
也许值得注意的是,func(void) 语法在 C++ 中并未被弃用,但它通常被认为更像是 C 风格的习惯用法。 我认为我遇到的大多数 C++ 程序员都更喜欢空参数列表。
引用 C++ 标准第 8.3.5 节第 2 段:
“如果参数声明子句为空,则函数不带参数。参数列表 (void) 相当于空参数列表。除了这个特殊的在这种情况下,void 不应是参数类型(尽管从 void 派生的类型,例如 void*,可以)。”
没有提到这两种形式都已被弃用。 再次感谢 Tribble 先生出色的网站为我指出了该标准的正确部分。
The previous answers are quite correct, but I'm linking to David Tribble's excellent page as it gives a great explanation on this and many other issues.
The highlights:
It's perhaps worth noting that the func(void) syntax is not deprecated in C++, but it's commonly considered more of a C-style idiom. I think most C++ programmers I've run across prefer the empty parameter list.
A quote from the C++ standard, section 8.3.5, paragraph 2:
"If the parameter-declaration-clause is empty, the function takes no arguments. The parameter list (void) is equivalent to the empty parameter list. Except for this special case, void shall not be a parameter type (though types derived from void, such as void*, can)."
There's no mention that either form is deprecated. Thanks again to Mr. Tribble's excellent website for pointing me to the correct section of the standard.
C11 N1570标准草案< /strong>
void f()
已弃用,建议使用void f(void)
:6.11.6 函数声明符:
简介:
详细讨论: https://stackoverflow.com/a/36292431/895245
C++11 N3337 标准草案 两者
都不是 < code>void f(void) 和
void f()
均已弃用。void f(void)
的存在是为了与 C 兼容。附录 C“兼容性”C.1.7 第 8 条:声明符:由于
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
C11 N1570 standard draft
void f()
is deprecated,void f(void)
recommended:6.11.6 Function declarators:
Introduction:
Detailed discussion: https://stackoverflow.com/a/36292431/895245
C++11 N3337 standard draft
Neither
void f(void)
norvoid f()
are deprecated.void f(void)
exists for compatibility with C. Annex C "Compatibility" C.1.7 Clause 8: declarators:Since
void f()
is deprecated in C andvoid f(void)
recommended,void f(void)
will exist for as long as C++ wants to maintain compatibility.void f(void)
andvoid f()
are the same in C++. So the longervoid f(void)
only makes sense if you care about writing code that compiles under both C and C++, which is likely not worth it.Detailed discussion: https://stackoverflow.com/a/36835303/895245
tl;dr:使用
void
。考虑到 C++ 中的向后兼容性以及下面指出的一些模糊之处,我断言我们会一直回到 K&R 和 ANSI C 以获得结论性的答案:
和..
我在这里将其余部分分成单独的讨论:
在不带参数的函数声明中指定使用 void 是否可以解决最令人烦恼的解析问题?
tl;dr: use
void
.Given the backward compatibility in C++, and the bit of ambiguity identified below, I assert that we go all the way back to K&R and ANSI C for a conclusive answer:
and..
I broke the rest into a separate discussion here:
Does specifying the use of void in the declaration of a function that takes no arguments address The Most Vexing Parse?
在 C++ 中,
int f(void)
确实是一个已弃用的声明,它 100% 等同于int f()
。 它是相同的签名。 在这种情况下,void
与空白一样重要。 这也意味着它们遵循“单一定义规则”(它们不会重载),并且Derived::f(void)
会覆盖Base::f()
。不过,不要搞乱像
f(const void)
这样的东西。 这种奇怪的现象意味着什么,目前还没有达成共识。In C++,
int f(void)
is indeed a deprecated declaration which is 100% equivalent toint f()
. It is the same signature. Thevoid
in this context is as significant as e.g. whitespace. That also means that they are subject to the One Definition Rule (they don't overload) andDerived::f(void)
overridesBase::f()
.Don't mess with stuff like
f(const void)
, though. There's not a lot of consensus what that kind of weirdness means.