为什么C ++代码缺少函数定义中的正式参数名称而没有警告?

时间:2010-02-23 16:08:08

标签: c++ compiler-warnings

在开始使用一些VS2005生成的MFC代码时,我注意到它覆盖了一个类似这样的方法:

void OnDraw(CDC* /*pDC*/)
{
    ...
    // TODO: Add your code here
}

当然,一旦我添加了一些东西,我就意识到我需要取消注释pDC形式参数才能进行编译,但我对于如何/为什么C ++函数可以编译(没有警告)感到困惑当形式参数只有一个类型而不是一个名字时:

void foo(int)
{
    int x = 3;
}
int main()
{
    foo(5);
    return 0;
}

这不应该产生至少一个警告(使用-Wall或/ W4)?它似乎没有。我错过了什么吗?有没有这种情况有用,或者只是因为编译器无法区分函数声明(只需要类型)和定义(完全指定)之间的区别,直到处理完行后?

4 个答案:

答案 0 :(得分:51)

因为有时您有一个接口所需的参数但该函数不使用它。也许参数不再是必需的,只有在必须使用相同签名的其他函数中才需要(特别是它们可以通过指针调用)或者功能尚未实现。由于这个原因,拥有未使用的参数在生成的或框架代码中特别常见(这可能是MFC生成的代码已注释掉名称的原因)。

至于为什么没有警告 - 我想这是因为这是一个问题是一个主观的事情,其他人(特别是编译器实施者)不认为这是一个问题。一旦你真正去使用参数,如果你忘记取消注释名称,你就会让编译器抱怨,这样只有当你真正需要编译时才会让编译器抱怨(编译器版本的敏捷YAGNI:“You Aren” t Get Neet It“哲学”。

当您发出警告时,通常会出现相反的情况 - 未使用的命名参数会生成警告 - 这也许就是为什么生成的函数将名称注释掉了。

答案 1 :(得分:17)

我见过的最常见的原因是抑制编译器会抛出的未使用的变量警告:

#include <iostream>

void foo(int source)
{
  std::cout << "foo()" << std::endl;
}

int main()
{
  foo(5);
  return 0;
}

gcc说:main.cc:3: warning: unused parameter 'source'

有两种常见的方法可以消除警告:注释变量名称或完全删除它:

void foo(int /*source*/)
{
  std::cout << "foo()" << std::endl;
}

void foo(int)
{
  std::cout << "foo()" << std::endl;
}

我强烈建议评论删除。否则,您的维护程序员必须找出该参数代表的其他方式。

Qt(可能还有其他框架)提供了一个宏来抑制警告而无需评论或删除变量名称:Q_UNUSED(<variable>)

void foo(int source)
{
  Q_UNUSED(source); // Removed in version 4.2 due to locusts
  std::cout << "foo()" << std::endl;
}

这使您可以在函数体中调用未使用该变量,并提供一个很好的位置来记录为什么不使用它。

答案 2 :(得分:5)

C ++ 11 N3337标准草案

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf说它在8.4.1 / 6是合法的  &#34;功能定义&gt;通常&#34;:

  

注意:无需命名未使用的参数。例如,

void print(int a, int) {
    std::printf("a = %d\n",a);
}

更准确地说,8.4.1 / 1表示函数定义的语法是

function-definition:
    attribute-specifier-seqopt decl-specifier-seqopt
    declarator virt-specifier-seqopt function-body

然后,如果您遵循语法定义,例如在&#34;附件A语法摘要&#34;下,您将看到名称是可选的。

答案 3 :(得分:2)

它编译,因为语言标准明确说它必须编译。没有其他答案。这是使C ++与C不同的位之一。在C中,函数定义中的参数名必须存在,在C ++中它们是可选的。

我真的很想知道你为什么问你的“为什么”这个问题。你觉得这种行为有什么不自然,不寻常或不合逻辑吗?