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 有误,或者这确实是一个错误?
有什么提示吗?提前致谢。
有问题的行在句法上是正确的。这两行代码都不是特别有用——都表现出未定义的行为——但它们是合法的 C++ 代码。因此,编译器没有义务发出任何诊断信息。
这只是一个实施质量问题 - 编译器在这种情况下没有义务发出警告,但发出警告时非常有用。至于为什么 clang 只对 y
而不是 x
发出警告,而 gcc 对两者都发出警告 - 我不确定。它绝对与包含的头文件无关(您可以通过在 main.cpp
中定义 What
来自己查看)并且可能与您正在打印 y
和再也不会阅读 x
。
但是您不能依赖这些警告的完全准确性。然而,当你得到它们时,它们总是值得关注的。
这不是 clang
错误,警告被抑制是因为 x
随后未被使用,我在下面引用的错误报告解释了此行为背后的基本原理。
在这种特定情况下,如果变量未被使用,它被认为是 clang feature 不产生此警告(Wuninitialized
),尽管大多数人可能会发现这种令人惊讶的行为。
我们可以从以下错误报告中看出原因:No uninitialized warning for self-initialization (e.g., int x = x):
Right, this is deliberate, and is considered to be a feature rather
than a bug. We suppress the warning on 'int x = x;' only in the case
where 'x' is otherwise unused.
BUG报告中提到self-intialization这种方式是:
considered the canonical way to suppress "use of uninitialized
variable" warnings
这不取决于所讨论的代码是否包含在 header 中,我整理了一个 live example 显示当代码全部在一个文件中时警告不会出现.
注意,这样初始化一个变量:
int x = x;
为未定义行为,参考见:
- Does initialization entail lvalue-to-rvalue conversion? Is
int x = x;
UB?
- Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++14?
所以一般来说,我们不能对结果有任何期望,编译器也没有义务发出诊断,尽管这样做会有所帮助。
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 有误,或者这确实是一个错误? 有什么提示吗?提前致谢。
有问题的行在句法上是正确的。这两行代码都不是特别有用——都表现出未定义的行为——但它们是合法的 C++ 代码。因此,编译器没有义务发出任何诊断信息。
这只是一个实施质量问题 - 编译器在这种情况下没有义务发出警告,但发出警告时非常有用。至于为什么 clang 只对 y
而不是 x
发出警告,而 gcc 对两者都发出警告 - 我不确定。它绝对与包含的头文件无关(您可以通过在 main.cpp
中定义 What
来自己查看)并且可能与您正在打印 y
和再也不会阅读 x
。
但是您不能依赖这些警告的完全准确性。然而,当你得到它们时,它们总是值得关注的。
这不是 clang
错误,警告被抑制是因为 x
随后未被使用,我在下面引用的错误报告解释了此行为背后的基本原理。
在这种特定情况下,如果变量未被使用,它被认为是 clang feature 不产生此警告(Wuninitialized
),尽管大多数人可能会发现这种令人惊讶的行为。
我们可以从以下错误报告中看出原因:No uninitialized warning for self-initialization (e.g., int x = x):
Right, this is deliberate, and is considered to be a feature rather than a bug. We suppress the warning on 'int x = x;' only in the case where 'x' is otherwise unused.
BUG报告中提到self-intialization这种方式是:
considered the canonical way to suppress "use of uninitialized variable" warnings
这不取决于所讨论的代码是否包含在 header 中,我整理了一个 live example 显示当代码全部在一个文件中时警告不会出现.
注意,这样初始化一个变量:
int x = x;
为未定义行为,参考见:
- Does initialization entail lvalue-to-rvalue conversion? Is
int x = x;
UB? - Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++14?
所以一般来说,我们不能对结果有任何期望,编译器也没有义务发出诊断,尽管这样做会有所帮助。