为什么未命名的参数警告在C和C++之间不一致
Why the unnamed parameter warning discrepency between C and C++?
我有下面的C/C++程序,编译时所有警告都在.上
int foo(int x) { return 5; }
C++编译器对未引用的形式参数发出警告。当我删除"x",使签名显示为"int foo(int)"时,编译器很高兴。
另一方面,C编译器喜欢命名参数,并在未命名时发出警告。
编辑:它会发出错误,而不是警告。
为什么有区别?理由是什么?
附言:我使用的是GNU编译器工具链。
它们是不同的语言,有不同的规则。
在C中,函数参数必须有名称;我很惊讶你得到的是警告而不是错误。我想理由是没有充分的理由使用一个未使用的参数;如果你不需要它,那么它为什么要存在呢?(当然,也有一些有效的情况可以忽略参数,例如使用指定特定参数集的函数指针时;据推测,当权者认为这不够普遍,不值得放松规则。如果你需要忽略它,那么(void)unused;
应该抑制你可能会收到的任何"未使用的参数"警告。)
在C++中,函数通常必须具有特定的签名,以便覆盖基类中声明的虚拟函数,或者匹配模板参数的特定用法。很可能不是所有重写都需要该签名的所有参数,在这种情况下,忽略该参数是非常合理的。我猜这就是允许你不具名的理由。
C的一个原因可能是它仍然有旧样式的参数列表,该列表仅由标识符组成:
int f(to)
double to; {
return to;
}
因此,基本上,当它只看到一个标识符时,它必须假设这是一个变量名,而不是一个类型。
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 = %dn",a); }
现在,关于这个更大的哲学问题,为什么C需要所有参数的标识符,无论它们是否使用,而C++没有,请记住以下内容:
- C比C++早十年左右
- C的设计使它的编译器易于编写
- C不支持函数重载
简言之,没有充分的理由让C允许未使用的参数不命名,至少有一个充分的理由(简化解析)让它不应该。
我也一直对此感到好奇,但在任何情况下,您都可以通过实际命名参数x
和在正文中的某个地方说:
(void)x;
正如您所说,您可以通过删除参数名称来修复C++中的警告。在C中,不允许省略参数名称。因此,如果你的C编译器产生了相同的警告,你将无法删除它。所以你的C编译程序不会产生这样的警告。
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 大小相等但成员数量不同的结构之间的性能差异
- 类与私有变量的其他类之间的线程安全性
- 如何在cpp文件之间切换窗口?在Qt中
- 线程之间的布尔停止信号
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 在 const 函数中通过引用和指针返回之间的区别
- 我想知道长双倍和双倍之间的区别
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 构造函数和转换运算符之间的重载解析
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数