Clang(3.6.0)忽略包含的头文件中的警告

时间:2015-06-20 22:34:21

标签: c++ clang clang++

似乎clang忽略了包含的头文件中出现的警告:

// what.hpp
class What {
public:
    What() {
        int x = x;
    }
};

// main.cpp
#include <iostream>
#include "what.hpp"
int main()
{
    int y = y;
    std::cout << "y is: " << y << std::endl;
    What w;
}

用g ++(4.9.2)编译它给出了:

$ g++ -dumpversion && g++ -Wall -Wextra main.cpp -o main
4.9.2
In file included from main.cpp:3:0:
what.hpp: In constructor ‘What::What()’:
what.hpp:5:17: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]
     int x = x;
             ^
main.cpp: In function ‘int main()’:
main.cpp:5:13: warning: ‘y’ is used uninitialized in this function [-Wuninitialized]
 int y = y;

用clang编译相同的东西:

$ clang++ --version && clang++ -Wall -Wextra main.cpp -o main
Ubuntu clang version 3.6.0-2ubuntu1~trusty1 (tags/RELEASE_360/final) (based on LLVM 3.6.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
main.cpp:5:13: warning: variable 'y' is uninitialized when used within its own initialization [-Wuninitialized]
int y = y;
    ~   ^
1 warning generated.

我不确定,如果我使用clang错误或者这确实是一个错误? 任何提示?提前谢谢。

2 个答案:

答案 0 :(得分:2)

这不是clang错误,警告被禁止,因为x随后未使用,我在下面引用的错误报告解释了此行为背后的基本原理。

在这种特定情况下,如果变量未被使用,则被认为是clang 功能不产生此警告(Wuninitialized),尽管大多数人可能会发现这种令人惊讶的行为。 / p>

我们可以从以下错误报告中看到基本原理:No uninitialized warning for self-initialization (e.g., int x = x)

  

是的,这是故意的,而且被认为是一个特征   而不是一个bug。我们在&#39; int x = x;&#39;上禁止警告在这种情况下仅   在哪里&#39; x&#39;否则没用。

在错误报告中提到,以这种方式进行自我初始化是:

  

考虑了抑制&未使用未初始化的规范方法   变量&#34;警告

这不取决于相关代码是否包含在标题中,我将live example放在一起,显示当代码全部在一个文件中时警告不显示。

注意,以这种方式初始化变量:

int x = x;

是未定义的行为,供参考:

所以一般来说,我们对结果没有任何期望,编译器也没有义务发出诊断,尽管这样做会有所帮助。

答案 1 :(得分:1)

有问题的行在语法上是正确的。两者都没有特别有用的代码行 - 都表现出未定义的行为 - 但它们是合法的C ++代码。因此,编译器没有义务发出任何诊断。

这只是一个执行质量问题 - 编译器没有义务在这种情况下发出警告,但是当它发生时它非常有用。至于为什么clang恰好警告y而不是x,而gcc警告两者 - 我不确定。它绝对与包含的头文件无关(您可以通过在What中定义main.cpp来亲眼看到)并且可能与您正在打印y和从来没有再次阅读x

但是你不能依赖完全准确地使用这些警告。然而,当你得到它们时,它们总是值得关注。