2

这个简化的示例代码在静态分析下引发了 C6001:

struct st_facade
{
    st_facade &operator=(const int new_value) { m_value = new_value; return *this;}

private:
    int m_value;
};

struct foo
{
    st_facade my_int;
};

void main()
{
    foo f;
    f.my_int= 0; // C6001: Using uninitialized memory 'f'.
}

我的理解是,之所以提出此警告,是因为假设重载的赋值运算符可能正在读取未初始化的内存。但在这种情况下,我们并没有这样做——我们实际上是在初始化内存。

如何告诉编译器这里的赋值运算符没有使用任何未初始化的内存?我尝试使用几种不同的 SAL 注释来表达这一点,但没有任何效果。

在这种情况下,零初始化内存(即使用foo f{};or st_facade my_int{};)不是正确的答案。在实际代码中,这样的初始化可能会产生不可接受的性能影响

[编辑] 出于类似的原因,基于构造函数的初始化也不是正确的答案。我们需要这种类型在创建时未初始化;我们需要通知静态分析器赋值运算符执行初始化。

[编辑 2] 更一般地说,我们需要一种方法来告诉静态分析器“此方法初始化对象”,而无需实现构造函数或对类型的每个实例进行零初始化。

4

1 回答 1

0

这就是 C++ 有构造函数的原因。

struct st_facade
{
    explicit st_facade(int value) 
        : m_value{ value } 
    {}
    
    st_facade &operator=(const int new_value) { m_value = new_value; return *this;}

private:
    int m_value;
};

struct foo
{
    explicit foo(int value)
        : my_int{ value }
    {}

    st_facade my_int;
};

int main()
{
    foo f{0};
}
于 2021-01-11T22:01:27.107 回答