为什么函数原型在不需要时包含参数名称?

时间:2011-03-08 15:00:55

标签: c++ naming function-prototypes

我一直认为函数原型必须包含函数的参数及其名称。但是,我只是尝试了这个:

int add(int,int);

int main()
{
    std::cout << add(3,1) << std::endl;
}

int add(int x, int y)
{
    return x + y;
}

它有效!我甚至尝试过极小心地编译:

g++ -W -Wall -Werror -pedantic test.cpp

它仍然奏效。所以我的问题是,如果你不需要函数原型中的参数名,为什么它这么常见呢?这有什么用途吗?它与函数的签名有关吗?

6 个答案:

答案 0 :(得分:17)

不,这些不是必需的,实际上被编译器忽略了。你甚至可以在不同的声明中给它们不同的名字;以下是完全合法的:

int foo(int bar);
int foo(int biz);
int foo(int qux) {
    ...
}

将它们放入的原因是文档:

  • 如果有人读取您的头文件,他们可以一眼就知道每个参数的用途。
  • 如果使用花哨的IDE,它会在您开始输入函数调用时显示参数名称。
  • Doxygen等文档工具可以解析参数名称并在文档中显示。

答案 1 :(得分:8)

参数名称是完全可选的,对编译没有影响。它们可能放在那里以便更好地阅读代码。

答案 2 :(得分:4)

声明中不需要参数名称。它们纯粹是文档。

您甚至不需要定义中的名称:

int f(int)
{
    return 0;
}

在C ++中编译得很好(尽管不在C语言中)。这有时对例如有用。继承,重载,函数指针。

答案 3 :(得分:3)

您不需要在函数原型中包含参数名称。您只需要完整的签名,其中包括参数类型和(在函数模板特化的情况下)返回值。

但是,为了编写自我记录代码,包含参数名称仍然很常见。也就是说,这个声明的函数是:

void foo(int number_of_foos_desired, string foo_replacement);
通过仅查看原型,

更容易理解,而不是这个:

void foo(int, string);

当您编写调用此函数的代码时,许多现代IDE也会在您键入时弹出参数名称。如果您没有在原型中包含参数名称,他们可能无法弹出此信息。

答案 4 :(得分:1)

它与函数的签名有很多关系。

使用.h文件的一个好处是,当有人出现并希望了解您的程序/ api所做的事情时,他们可以查看您的头文件并了解正在执行的操作,他们的输入和输出,一切如何在一起等等。

如果您遇到类似

的方法
int doStuff(int,int)

这比具有签名的方法的说法要少得多:

int doStuff(int firstNumberToAdd, int secondNumberToAdd);

第二个,你至少可以了解正在进行的操作以及正在发生的事情。这是编写自我记录代码背后的想法。

如果您有兴趣,可以查看Steve McConnell编写的Code Complete。

答案 5 :(得分:1)

有不同的场景。我发现在处理inheritancevirtual functions方面非常有帮助。如果您使用的virtual function在子类中生成未使用的警告,则可以省略变量名称。