我有以下C / C ++程序,并且我在编译时会显示所有警告。
int foo(int x) { return 5; }
C ++编译器给我一个关于未引用的形式参数的警告。当我删除“x”以使签名为“int foo(int)”时,编译器很高兴。
另一方面,C编译器喜欢命名参数,并在未命名时发出警告。
编辑:它发出错误,而不是警告。
为何与众不同?理由是什么?
P.S。我正在使用GNU编译器工具链。
答案 0 :(得分:9)
它们是不同的语言,具有不同的规则。
在C中,函数参数必须具有名称;我很惊讶你收到警告而不是错误。我想基本原理是没有充分理由使用未使用的参数;如果你不需要它,为什么它应该存在? (当然,有一些忽略参数的有效情况,例如当使用指定一组特定参数的函数指针时;可能会认为这些函数不够常见,不值得放宽规则。如果需要要忽略它,那么(void)unused;
应该禁止你可能获得的任何“未使用的参数”警告。)
在C ++中,函数通常必须具有特定的签名,以便覆盖在基类中声明的虚函数,或者匹配模板参数的特定用法。很可能并非所有覆盖都需要该签名的所有参数,在这种情况下忽略该参数是非常合理的。我猜这是让你不知名的理由。
答案 1 :(得分:2)
C的一个原因可能是它仍然具有仅包含标识符的旧式参数列表:
int f(to)
double to; {
return to;
}
所以基本上当它只看到一个标识符时,它必须假设这是一个变量名而不是一个类型。
答案 2 :(得分:1)
C和C ++是不同的语言,具有不同的规则,这是许多区域中的一个,它们的行为与其他区域不同。
6.9.1功能定义
...
5如果声明者包含参数类型列表,每个参数的声明应该 包括标识符,但由单个参数列表组成的特殊情况除外void
类型的参数,在这种情况下不应有标识符。没有声明清单 应遵循。
强调我的。
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 ++没有使用的更大的哲学问题,请记住以下内容:
简而言之,没有充分的理由说明为什么C应该允许未使用的参数未命名,并且至少有一个很好的理由(简化解析)为什么不应该。
答案 3 :(得分:0)
我也总是对此感到疑惑,但无论如何,你可以通过实际命名参数x
并在身体的某个地方说:
(void)x;
答案 4 :(得分:0)
正如您所说,您可以通过删除参数名称来修复C ++中的警告。在C中,不允许遗漏参数名称。因此,如果您的C编译器产生相同的警告,则无法将其删除。所以你的C编译器不会产生这样的警告。