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

And*_*son 43 c++ compiler-warnings

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

void OnDraw(CDC* /*pDC*/)
{
    ...
    // TODO: Add your code here
}
Run Code Online (Sandbox Code Playgroud)

所以,当然,只要我补上一我意识到我需要以编译取消注释在PDC正式的说法,但我很困惑,如何/为什么在C++函数可以编译(无警告)何时正式参数只有一个类型,而不是一个名称:

void foo(int)
{
    int x = 3;
}
int main()
{
    foo(5);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

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

Mic*_*urr 52

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

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

当您启动警告时 - 通常会发生相反的情况 - 未使用的命名参数会生成警告 - 这也许是生成的函数注释掉名称的原因.


Bil*_*ill 18

我见过的最常见的原因是抑制编译器将要引发的未使用的变量警告:

#include <iostream>

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

int main()
{
  foo(5);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

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

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

void foo(int /*source*/)
{
  std::cout << "foo()" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

void foo(int)
{
  std::cout << "foo()" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

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

Qt(可能还有其他框架)提供了一个宏,它可以在不需要注释或删除变量名的情况下抑制警告Q_UNUSED(<variable>)::

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

这使您可以在该变量未使用的函数体中调出,并给出了一个伟大的地方来记录,为什么不使用它.

  • @Bill:但它仍然是一个有价值的注释(我发现自己偶尔会被C对参数名称的坚持所激怒) (2认同)

Cir*_*四事件 6

C++ 11 N3337标准草案

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf表示它是合法的8.4.1/6"功能定义>一般":

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

void print(int a, int) {
    std::printf("a = %d\n",a);
}
Run Code Online (Sandbox Code Playgroud)

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

function-definition:
    attribute-specifier-seqopt decl-specifier-seqopt
    declarator virt-specifier-seqopt function-body
Run Code Online (Sandbox Code Playgroud)

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