Clang(3.6.0)忽略包含头文件中的警告
Clang (3.6.0) ignores warnings from included header files
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,还是这真的是一个bug?有什么提示吗?提前谢谢。
这不是clang
错误,由于x
随后未被使用,警告被抑制,我在下面引用的错误报告解释了这种行为背后的基本原理。
在这种特定情况下,如果变量未使用,则不产生此警告(Wuninitialized
)被视为clang功能,尽管大多数人可能会发现这种令人惊讶的行为。
我们可以从以下错误报告中看到基本原理:自初始化没有未初始化警告(例如,int x=x):
是的,这是经过深思熟虑的,而且被认为是一个特点而不是一个bug。我们取消对"int x=x;"的警告仅在这种情况下其中"x"在其他方面未使用。
错误报告中提到,以这种方式进行的自我初始化是:
被认为是抑制"未初始化的使用"的规范方法变量"警告
这并不取决于有问题的代码是否包含在头中,我举了一个实际的例子,显示当代码都在一个文件中时,警告不会显示。
注意,以这种方式初始化变量:
int x = x;
是未定义的行为,请参阅:
- 初始化是否需要左值到右值的转换?
int x = x;
是UB吗 - C++标准在C++14中使用不确定值和未定义行为方面是否发生了变化
因此,一般来说,我们对结果没有任何期望,编译器也没有义务发布诊断,尽管这样做可能会有所帮助。
有问题的行在语法上是正确的。两者都不是特别有用的代码行——都表现出未定义的行为——但它们是合法的C++代码。因此,编译器没有义务发布任何诊断。
这只是一个实现质量问题——在这种情况下,编译器没有义务发出警告,但当它发出警告时会非常有用。至于为什么clang只警告y
而不警告x
,而gcc同时警告两者——我不确定。它肯定与所包含的头文件无关(您可以通过在main.cpp
中定义What
来亲眼看到),可能与您正在打印y
并且再也不会从x
中读取有关。
但您不能依赖这些警告的完全准确性。然而,当你得到它们时,它们总是值得关注的。
- 使用mongocxx驱动程序时包含头文件问题
- 如何为包含头文件的目标编写生成文件?
- 如何在 CMakeLists.txt Qt Creator 中包含头文件?
- 当包含头文件的文件不在根项目文件夹中时,如何包含它
- 在生成文件先决条件中包含头文件的原因
- My Project的属性配置正确,但Visual Studio仍然无法打开包含头文件
- 在 PostgreSQL C 扩展中包含头文件
- 是否可以在C++中以间接方式包含头文件
- 是否需要包含头文件?
- 如何在不包含完整的文件系统头的情况下使用文件系统的类路径C++17?
- 我收到未声明的标识符错误,但我已包含头文件?
- 为什么我们需要构建一个提升库,仅仅包含头文件还不够吗,因为提升是模板
- C++:当顺序真正重要时,如何保证在项目中包含头文件的顺序
- 如何在C++中包含头文件时错误地重载
- 我在C++中无效使用不完整的类型类错误,如何正确包含头文件?
- 虚幻引擎4.16,C++包含头文件
- C++多次包含头文件
- 令牌之前的预期类名 '{' - 包含头文件和 CPP 文件
- 可以将标头文件包含在多个源文件中,而无需重复保护
- 有条件地将文件包含在C++标头中