C++ 或 C 中的 foo(void) 和 foo() 有区别吗?

Posted

技术标签:

【中文标题】C++ 或 C 中的 foo(void) 和 foo() 有区别吗?【英文标题】:Is there a difference between foo(void) and foo() in C++ or C? 【发布时间】:2010-09-08 05:44:31 【问题描述】:

考虑这两个函数定义:

void foo()  

void foo(void)  

这两者有什么区别吗?如果不是,为什么void 参数在那里?审美原因?

【问题讨论】:

对于 C,Q/A 是 here 【参考方案1】:

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

【讨论】:

"prototype" 表示参数列表声明和返回类型。我这样说是因为“原型”一开始让我对你的意思感到困惑。【参考方案2】:

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

此外,如果函数声明不包含参数,如 在

double atof();

这也被认为意味着对 atof 的论点;关闭所有参数检查。这个特别 空参数列表的含义旨在允许较旧的 C 用新编译器编译的程序。但是使用它是个坏主意 与新程序。如果函数接受参数,则声明它们;如果 它不需要参数,使用 void。

【讨论】:

但问题是关于定义的,在这种情况下,相关的 C 规则是 作为该函数定义一部分的函数声明符中的空列表指定该函数没有参数。 【参考方案3】:

C中:

void foo() 表示“一个函数 foo 采用未指定数量的未指定类型的参数” void foo(void) 表示“一个函数 foo 不带参数”

C++ 中:

void foo() 表示“一个函数 foo 不带参数” void foo(void) 表示“一个函数 foo 不带参数”

因此,通过编写foo(void),我们在两种语言之间实现了相同的解释并使我们的标题多语言(尽管我们通常需要对标题做更多的事情以使它们真正跨语言;即,将它们包装在如果我们正在编译 C++,则为 extern "C")。

【讨论】:

但如果 C++ 需要 void,那么它本可以避免“最棘手的解析”问题。 没错,但是 C++ 中还有很多其他糟糕的解析,因此对其中任何一个进行审查都没有真正意义。 在最近的一个问题上,@James Kanze 发布了一个有趣的花絮。在这里重新发布以避免丢失:C 的第一个版本不允许指定函数可能采用的参数数量,因此 void foo() 是声明函数的唯一语法。当引入签名时,C 委员会必须从旧语法中消除无参数的歧义,并引入 void foo(void) 语法。 C++ 采用它是为了兼容性。 你能给我一个 C C90 及以后使用void foo() 而不是void foo(void) 会产生功能差异的例子吗? IE。我用了很多年没有void的版本,没发现有什么问题,是不是漏了什么? @chacham15 void foo() if ( rand() ) foo(5); 编译并运行(除非你很幸运,否则会导致未定义的行为),而 void foo(void) 使用相同的主体会导致编译错误。【参考方案4】:

C++11 N3337 标准草案

没有区别。

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

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

8.3.5 更改:在 C++ 中,使用空参数列表声明的函数不接受任何参数。在 C 中,一个空的 参数列表表示函数参数的数量和类型未知。

例子:

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

基本原理:这是为了避免错误的函数调用(即,使用错误数量或类型的函数调用 论据)。

对原始特征的影响:改变定义明确的特征的语义。此功能在 C 中被标记为“过时”。

8.5.3 函数 说:

4。 parameter-declaration-clause 确定可以指定的参数及其处理,当 该函数被调用。 [...] 如果参数声明子句为空,则函数 不接受任何论据。参数列表(void)相当于空参数列表。

C99

如 C++11 所述,int f() 未指定任何有关参数的内容,并且已过时。

它可以导致工作代码或 UB。

我已经在https://***.com/a/36292431/895245详细解释了C99标准

【讨论】:

语法高亮在“means int”附近关闭。你能修好它吗?例如,在 cmets 内关闭或“void”更像here。

以上是关于C++ 或 C 中的 foo(void) 和 foo() 有区别吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 void* 转换为 foo* 以符合 C++?

处理类 new 和 delete 运算符 C++ 中的内存泄漏

无法将派生类 push_back() 推入 C++ 中的 STL 列表

C、C++ 和 C# 中的 void 是啥意思?

即使放入标头c ++也无法内联函数

函数调用或构造函数调用中的 C++ 数组初始化