代码很简单:
class AAA {};
AAA a;
int main() {
AAA x = a;
AAA y(a);
}
对于带有-std=c++11 -Wall
的g ++ 4.8,它仅针对第一行提供警告:
警告:变量'x'设置但未使用[-Wunused-but-set-variable]
对于带/Za /W3
的vc12,它仅针对第二行发出警告:
警告C4101:'y':未引用的局部变量
为什么编译器对代码的处理方式不同?似乎g ++认为y
为已使用,而vc认为x
为已使用。那背后的编译器逻辑是什么?
编辑:据我测试,所涉及的变量的顺序和数量无关紧要。重要的只是初始化的形式(复制初始化与直接初始化)。我问了这个问题,以防我不知道这两种初始化形式之间的区别,这种形式由编译器的行为反映出来(我所知道的差异是隐式和显式复制构造函数调用)。编译器在发出警告方面确实有很多自由,但最重要的是它们具有有意义和自我一致的逻辑,对吗?
答案 0 :(得分:3)
在/ 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,并且被给予更高的警告级别以避免在工具链更新期间向遗留代码中引入新警告)。
答案 1 :(得分:0)
C ++标准仅要求对某些错误进行诊断,并且不区分“错误”和“警告”命令。就formaleese而言,不要在键盘上闪烁灯光可能是一种严肃的态度。所以编译器有很大的自由度,而C ++编译器中的其他许多东西都是由市场强制推动的,而不是标准的。
不同的编译器可以发出什么类型的警告,commaon选项的含义(特别是“所有”警告),以及他们如何随意选择警告和不警告。
如果您真的对此感兴趣,可以尝试测试有关给定编译器的各种假设。例如,删除警告的变量,是否会使编译器警告另一个?三个未使用的变量怎么样,你会得到一个,两个或三个警告吗?声明的顺序是否重要?等等。