为什么编译器对auto x=a给出不同的警告消息;和auto x(a)

Why compilers give different warning message for auto x = a; and auto x(a);?

本文关键字:auto 消息 警告 编译器 为什么      更新时间:2023-10-16

代码很简单:

class AAA {};
AAA a;
int main() {
AAA x = a;
AAA y(a);
}

对于带有-std=c++11 -Wall的g++4.8,它只对第一行发出警告:

警告:变量'x'设置但未使用[-Wunused但设置变量]

对于带有/Za /W3的vc12,它只对第二行发出警告:

警告C4101:"y":未引用的局部变量

为什么编译器对待代码的方式不同?似乎g++认为y使用,vc认为x使用。编译器的逻辑是什么?

编辑:就我所测试的而言,所涉及的变量的顺序和数量并不重要。唯一重要的是初始化的形式(复制初始化与直接初始化)。我问了这个问题,以防我不知道编译器行为所反映的这两种初始化形式之间的区别(我知道的区别是隐式与显式复制构造函数调用)。编译器在发出警告方面确实有很大的自由,但归根结底,他们有自己有意义和自我一致的逻辑,对吧?

At/W4,Visual C++2013报告:

x.cpp(6) : warning C4101: 'y' : unreferenced local variable
x.cpp(5) : warning C4189: 'x' : local variable is initialized but not referenced

使用Visual C++时,请始终在/W4处编译(并可选择打开您关心的其他警告)。这两个警告的警告级别的差异可能是由于历史原因(例如,C4109是后来添加的,并且被赋予了更高的警告级别,以避免在工具链更新期间将新的警告引入到遗留代码中)。

C++标准只需要对某些错误进行诊断,而不区分"错误"answers"警告"诊断。就形式而言,键盘上的灯不闪烁可能是一种诊断。因此,编译器有着巨大的自由度,与C++中的许多其他编译器一样,编译器是由市场而非标准强迫的。

不同的编译器在可以发出什么样的警告、commaon选项的含义(特别是"所有"警告)以及如何任意选择警告和不警告方面有所不同。

如果你真的对此感兴趣,你可以进行实验来测试关于给定编译器的各种假设。例如,删除被警告的变量,是否会使编译器对另一个发出警告?三个未使用的变量呢?然后你会收到一个、两个或三个的警告吗?申报的顺序重要吗?等等。