代码之家  ›  专栏  ›  技术社区  ›  SmacL

f(void)在现代C和C++中是否被弃用?[副本]

  •  68
  • SmacL  · 技术社区  · 17 年前

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

    int f(void)
    

    我倾向于这样写:

    int f()
    

    为了提高一致性,是否有任何理由不在整个代码库中用()替换(void),或者两者之间是否存在我不知道的微妙差异?

    更具体地说,如果C++中的虚拟成员函数被描述为:

    virtual int f(void)
    

    并且派生类包括成员函数:

    int f()
    

    这是有效的覆盖吗?此外,我是否可能会遇到基于几乎相同签名的链接器问题?

    6 回复  |  直到 4 年前
        1
  •  101
  •   Daniel Daranas    12 年前

    在C中,声明 int f(void) 表示返回不带参数的int函数。宣言 int f() 表示一个返回int的函数,该函数接受任意数量的参数。因此,如果你在C中有一个不接受参数的函数,那么前者就是正确的原型。

    在C++中,我相信 int f(无效) 已弃用,以及 int f() 因为它具体意味着不需要参数的函数。

        2
  •  21
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    添加到 Chris's answer ,使用 int f() 根据我的经验,这在C中是不好的做法,因为你失去了编译器将函数的声明与其定义进行比较的能力,以确保它被正确调用。

    例如,以下代码符合标准C:

    #include <stdio.h>
    
    void foo();
    
    void bar(void) {
        foo();
    }
    
    void foo(int a) {
        printf("%d\n", a);
    }
    

    但它会导致未定义的行为,因为 a 未传递给 foo .

    在C++中,有两个版本 足球 :一个不接受争论,一个接受 int 所以 bar 最终调用未定义的版本,这将导致链接器错误(假设没有其他定义 足球 任何地方)。

        3
  •  18
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    前面的答案非常正确,但我链接到David Tribble的优秀页面,因为它提供了一个 great explanation 在这个问题和许多其他问题上。

    亮点:

    C区分函数 用空参数列表声明 以及用a声明的函数 参数列表仅包含 无效。前者是未打印的 函数取一个未指定的数字 争论,而后者是 原型函数不接受 论据。

    另一方面,C++没有 两者之间的区别 声明,并考虑两者 意思是函数取否 论据。

    对于旨在 编译为C或C++,最好 解决这个问题的办法是始终 声明不带参数的函数 具有明确的空洞原型。

    空函数原型是 C99中已弃用的功能(因为 位于C89)。

    也许值得注意的是,func(void)语法是 在C++中已被弃用,但它通常被认为更像是一种C风格的习语。我认为我遇到的大多数C++程序员更喜欢空参数列表。

    引用C++标准第8.3.5节第2段:

    如果参数声明子句为空,则函数不接受任何参数。参数列表(void)等效于空参数列表。除此特殊情况外,void不应是参数类型(尽管从void派生的类型,如void*,可以)

    没有提到这两种形式都被弃用。再次感谢Tribble先生出色的网站为我指出了标准的正确部分。

        4
  •  2
  •   Community Mohan Dere    8 年前

    C11 N1570 standard draft

    void f() 已弃用, void f(void) 推荐:

    6.11.6函数声明器 :

    1. 使用带空括号的函数声明符(不是原型格式参数 类型声明器)是一个过时的功能。

    介绍 :

    2某些功能已经过时,这意味着它们可能会被考虑 在本国际标准的未来修订中撤销。它们之所以被保留,是因为 它们的广泛使用,但它们在新实现中的使用(用于实现 功能)或新程序(用于语言[6.11]或库功能[7.31])。

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

    C++11 N3337 standard draft

    也不 void f(无效) 也没有 无效f() 已弃用。

    void f(无效) 为了与C兼容而存在。 附件C“兼容性”C.1.7第8条:声明人 :

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

    自从 无效f() 在C中已弃用,并且 void f(无效) 推荐, void f(无效) 只要C++想要保持兼容性,它就会存在。

    void f(无效) 无效f() 在C++中也是一样的。所以时间越长 void f(无效) 只有当你关心编写在C和C++下编译的代码时才有意义,这可能不值得。

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

        5
  •  2
  •   Peter Mortensen Pieter Jan Bonestroo    4 年前

    太长了,读不下去了:使用 void .

    考虑到C++的向后兼容性,以及下面发现的一些模糊性,我断言我们可以一直追溯到K&R和ANSI C得出结论性答案:

    int getline(void);
    int copy(void)
    

    由于getline和copy的专用版本没有参数, 逻辑表明,他们的原型在文件开头 应该 getline() copy() 。但为了兼容 旧的C程序标准采用空列表作为旧样式 声明,并关闭所有参数列表检查;单词 无效的 必须用于显式空列表。 [Kernighan和Richie,《C编程语言》,1988年,第32-33页]

    还有。。

    空参数列表的特殊含义旨在允许 使用新编译器编译旧的C程序。但这不是个好主意 在新程序中使用它。如果函数接受参数,则声明 他们;如果不需要论证,请使用void[同上,第73页]

    我在这里把剩下的分成单独的讨论: Does specifying the use of void in the declaration of a function that takes no arguments address The Most Vexing Parse?

        6
  •  -1
  •   hochl Michael Aaron Safyan    8 年前

    在C++中, int f(void) 确实是一个已弃用的声明,100%等同于 int f() 相同的签名。这个 void 在这种情况下,它和空白一样重要。这也意味着它们受一个定义规则的约束(它们不会过载) Derived::f(void) 凌驾 Base::f() .

    不要弄乱像这样的东西 f(const void) 不过。对于这种怪异意味着什么,人们并没有达成太多共识。