没有缺少 ctor 初始化列表的警告?

no warning for missing ctor initializer list?

此代码缺少构造函数初始化列表:

#include <cstdio>

struct s { 
    s() {}  // should be s(): m() {}
    int m;
};

int main() {
    struct s *px = new s();
    if (px->m) {
        printf("true\n");
    } else {
        printf("false\n");
    }
    delete px;
    return 0;
}

gcc 编译干净,没有警告:

$ g++ -Wall -Wextra -g -O2 test.cpp

但是,valgrind 知道 class 成员 m 没有初始化:

$ valgrind ./a.out
==10953== Conditional jump or move depends on uninitialised value(s)
==10953==    at 0x400512: main (test.cpp:10)
==10953== 

为什么 gcc 没有警告缺少初始化(-Wmissing-field-initializers-Wuninitialized-Wmaybe-uninitialized)?

有没有我可以通过的标志来捕获这种情况?

您可以添加 -Weffc++ 来捕捉它(灵感来自 Scott Meyers 的书“Effective C++”)。奇怪的是,它没有引用任何其他 -W 选项(clang++ 也没有)。

然而,有些人认为该选项现在有点过时,但在这种情况下,它发现了一个真正的问题。

GCC 也有 -fanalyzer 标志,它比警告标志做一些更深入的静态分析,并且可以在当前主干上捕获这种特定情况(但不是在 GCC 11.2 或更早版本中):

<source>:10:13: warning: use of uninitialized value '*px.s::m' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
   10 |     if (px->m) {
      |         ~~~~^
  'int main()': events 1-2
    |
    |    9 |     struct s *px = new s();
    |      |                          ^
    |      |                          |
    |      |                          (1) region created on heap here
    |   10 |     if (px->m) {
    |      |         ~~~~~             
    |      |             |
    |      |             (2) use of uninitialized value '*px.s::m' here
    |

但我似乎经常对生成误报的标志有问题。例如,在这种情况下,它抱怨 operator new 可能会返回一个空指针,这永远不会发生 (bug)。

详情见docs