c++ - Clang++ 无法检测到未初始化成员变量的使用
问题描述
使用带有编译器标志的 clang++ 版本 11 和 C++ 17,-Wall
如果在初始化之前使用变量,clang 通常会报错。但是,它不会检测到以下情况:
struct Bar
{
bool b1;
};
class Foo {
public:
Foo()
: b2(Bar{b2}.b1) // We are using b2 here before it is initialized, but clang doesn't complain
{ }
bool b2;
};
这是我可以创建的最简单的示例。它似乎只在使用对象(Bar)的成员变量(b1)初始化构造函数(在本例中为 b2)中的成员变量时发生。有谁知道为什么 clang 无法在这里检测到问题?
我承认这是一个人为的例子,但它实际上给我带来了一个问题,我想理解它。
解决方案
在一般情况下,无法在初始化之前检测您是否使用了成员变量。对一般程序这样做违反了赖斯定理。
编译器不要尝试。
相反,他们有一些简单而廉价的启发式方法来捕捉常见情况。
您不能依赖编译器来检测使用未初始化变量的每种情况。
在这种特殊情况下,您b2
在初始化之前传递给另一个类,但仅使用它来初始化临时变量。然后用于初始化最初初始化的变量。
如果这是你最简单的情况,clang 做得很好。当您将变量用作其自己的初始化语句的一部分时,编译器往往会更糟。
这是一个更简单的情况:
class Foo {
public:
Foo()
: b2((bool const&)b2) // We are using b2 here before it is initialized, but clang doesn't complain
{ }
bool b2;
};
另一个案例:
struct Bob {
bool b;
operator bool() const{ return b; }
};
class Foo {
public:
Foo()
: b2(Bob{b2}) // We are using b2 here before it is initialized, but clang doesn't complain
{ }
bool b2;
};
其他
Bob bob = {Bob{bob.b}.b};
我可以继续。
Clang并不声称可以检测所有未初始化的变量使用。因此,它未能检测到一个不是“错误”。相反,让他们检测另一个未初始化的案例是一项新功能。
推荐阅读
- docker - Docker not running/starting in MacOS mojave and fails with supervisor has failed message
- python - 优化递归代码以从输入数组生成有效数组
- php - How to load mysqli extension inside docker-compose.yml file with NGINX, PHP-FPM
- angular - Dates not binding in Angular
- python - Pytest 正在搜索更高一级的 conftest
- html - Applying image to grid
- python - 如何获取单个行的值?
- jquery - How to replace .bind() and .unbind() in script that appends and adds classes?
- c++ - Restrict enum class number of bits
- r - 限制来自shinyWidgets 包的multiInput() 中选定项目的数量