编译器未捕获未初始化的成员。这是一个错误吗?

Uninitialized member not caught by compiler. Is it a bug?

作为一个糟糕的 c++ 程序员,我今天遇到了这个段错误:一个未初始化的 shared_ptr 给了一个 NULL,我的程序崩溃了。对于普通 class 成员,如果成员未初始化,我会收到警告或错误。但在这种情况下不是。我在下面制作了一个复制品。

在调试模式下,此段错误。我没有收到关于未初始化变量的编译器错误或警告,这符合我的预期。

这是一个错误吗?还是我误会了。 编译器是否应该对此代码发出警告或错误?

我根本不想编译它!

我认为编译器应该会出错并提示您需要在 class 构造函数中初始化私有 wooo...

#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class Wooo{
public:
    int maybe;
    int istrue(){
        return maybe + 1;}
private:
    Wooo(); // just to be explicit about deleted default constructor
};

class Weee{
public:
    Weee(){}; // just empty constructor. reading wooo anywhere will give a NULL
    
    Wooo seg_me(){
        return *wooo.get();
    };
private:
    const std::shared_ptr<Wooo> wooo;
};

int main()
{   
    auto w = Weee();
    cout<<"Hello World\n";
    cout<< w.seg_me().istrue() << "\n";

    return 0;
}


an uninitialized shared_ptr ...

I think that the compiler should error out and say that you need to initialize the private wooo

不是未初始化。它只是默认初始化的。通过其默认构造函数。至 nullptr.

一个未显式初始化的shared_ptr等同于一个像

这样的原始指针
Wooo *wooo = nullptr;

Is this a bug?

是的,这是您代码中的错误:您允许指针默认初始化,然后在实际指向某处之前取消引用它。


你有两种可能的情况:

  1. 绝不允许Weee::wooo包含nullptr

    在这种情况下,错误是您编写的构造函数未能建立您的 class 不变量。

    你应该

    Weee() : wooo{make_shared ...} {}
    

    and/or

    explicit Weee(shared_ptr<Wooo>&& p) : wooo{std::move(p)} {}
    

    或其他什么。

    要点是 if 有一个非 nullptr 成员是 class 不变量,那么 any 构造函数或方法可能留下这个不满意是错误的。

  2. 有时允许 Weee::wooo 包含 nullptr,因为您有两阶段初始化 (boo) 或者因为它实际上是可选的或有条件的。

    在这种情况下,错误是您在取消引用之前没有检查指针是否(完全合法)nullptr