为什么C和C ++之间的未命名参数警告差异?

时间:2012-08-29 15:52:33

标签: c++ c

我有以下C / C ++程序,并且我在编译时会显示所有警告。

int foo(int x) { return 5; }

C ++编译器给我一个关于未引用的形式参数的警告。当我删除“x”以使签名为“int foo(int)”时,编译器很高兴。

另一方面,C编译器喜欢命名参数,并在未命名时发出警告。

编辑:它发出错误,而不是警告。

为何与众不同?理由是什么?

P.S。我正在使用GNU编译器工具链。

5 个答案:

答案 0 :(得分:9)

它们是不同的语言,具有不同的规则。

在C中,函数参数必须具有名称;我很惊讶你收到警告而不是错误。我想基本原理是没有充分理由使用未使用的参数;如果你不需要它,为什么它应该存在? (当然,有一些忽略参数的有效情况,例如当使用指定一组特定参数的函数指针时;可能会认为这些函数不够常见,不值得放宽规则。如果需要要忽略它,那么(void)unused;应该禁止你可能获得的任何“未使用的参数”警告。)

在C ++中,函数通常必须具有特定的签名,以便覆盖在基类中声明的虚函数,或者匹配模板参数的特定用法。很可能并非所有覆盖都需要该签名的所有参数,在这种情况下忽略该参数是非常合理的。我猜这是让你不知名的理由。

答案 1 :(得分:2)

C的一个原因可能是它仍然具有仅包含标识符的旧式参数列表:

int f(to)
double to; {
  return to;
}

所以基本上当它只看到一个标识符时,它必须假设这是一个变量名而不是一个类型。

答案 2 :(得分:1)

C和C ++是不同的语言,具有不同的规则,这是许多区域中的一个,它们的行为与其他区域不同。

C 2011 standard

6.9.1功能定义

...
5如果声明者包含参数类型列表,每个参数的声明应该 包括标识符,但由单个参数列表组成的特殊情况除外 void类型的参数,在这种情况下不应有标识符。没有声明清单 应遵循。

强调我的。

C++ 2011 Draft Standard

8.4功能定义[dcl.fct.def]

8.4.1一般[dcl.fct.def.general]

...
6 [注意:不需要命名未使用的参数。例如,

void print(int a, int) {
std::printf("a = %d\n",a);
}
- 结束说明]

现在,关于为什么 C需要所有参数的标识符而不管它们是否被使用而C ++没有使用的更大的哲学问题,请记住以下内容:

  1. C比C ++早了十年左右;
  2. C的设计使编译器易于编写;
  3. C不支持函数重载
  4. 简而言之,没有充分的理由说明为什么C应该允许未使用的参数未命名,并且至少有一个很好的理由(简化解析)为什么不应该

答案 3 :(得分:0)

我也总是对此感到疑惑,但无论如何,你可以通过实际命名参数x并在身体的某个地方说:

来使它同时工作。
(void)x;

答案 4 :(得分:0)

正如您所说,您可以通过删除参数名称来修复C ++中的警告。在C中,不允许遗漏参数名称。因此,如果您的C编译器产生相同的警告,则无法将其删除。所以你的C编译器不会产生这样的警告。