3

我有以下 C/C++ 程序,我编译它时显示所有警告。

int foo(int x) { return 5; }

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

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

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

为什么有区别?理由是什么?

PS 我正在使用 GNU 编译器工具链。

4

5 回答 5

9

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

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

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

于 2012-08-29T16:09:12.833 回答
3

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

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

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

于 2012-08-29T16:40:28.340 回答
1

C 和 C++ 是具有不同规则的不同语言,这是它们的行为与其他语言不太相似的众多领域之一。

C 2011 标准

6.9.1 函数定义

...
5 如果声明符包含参数类型列表,则每个参数的声明都应包含一个标识符,但参数列表由一个类型的单个参数组成的特殊情况除外void,在这种情况下不应有标识符。不得附有申报清单。

强调我的。

C++ 2011 标准草案

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 不支持函数重载

简而言之,没有充分的理由说明 C 应该允许未命名未使用的参数,并且至少有一个充分的理由(简化解析)为什么它不应该

于 2012-08-29T17:10:20.620 回答
0

我也一直想知道这一点,但无论如何,您可以通过实际命名参数来使其在两者中起作用x,并在正文中的某处说:

(void)x;
于 2012-08-29T16:07:10.157 回答
0

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

于 2012-08-29T16:08:31.183 回答