Clang++ 未能检测到未初始化成员变量的使用

Clang++ Fails To Detect Use of Uninitialized Member Variable

使用带有编译器标志 -Wall 的 clang++ 版本 11 和 C++ 17,如果您在变量初始化之前使用它,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 传递给另一个 class,但仅使用它来初始化临时变量。然后用于初始化最初初始化的变量。

如果这是您最简单的情况,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 不声称 检测所有未初始化变量的使用。所以它未能检测到一个不是“错误”。相反,让他们检测另一个未初始化的案例是一项新功能。