23
struct Bar
{
    Bar() {}
};


struct Foo
{
    Foo() = default;
    Bar m_bar;
};

int main()
{
    Foo foo;
}

当使用 C++11default关键字和 gcc 警告-Weffc++时,gcc 输出:

警告:'Foo::m_bar' 应该在成员初始化列表中初始化 [-Weffc++]

忽略此警告是否安全?我应该向 gcc 提交错误吗?

4

2 回答 2

29

您可以忽略或抑制警告。这是对有效 C++ 指南之一的误解。该指南说更喜欢初始化而不是分配,但在您的示例中,m_bar将被初始化。你的代码是正确的。

资料来源:GCC 的错误跟踪器中的Jonathan Wakely :

# Item 12: 在构造函数中优先初始化而不是赋值。

替换为第 4 项:“确保在使用对象之前对其进行初始化”,并且 G++ 无论如何都会误解原始项并警告任何 没有 mem-initializer 的成员,这非常烦人:初始化 std:: 没有意义字符串,它有一个完全安全的默认构造函数。我的 PR 2972​​ 的 -Wmeminit 补丁应该替换此项目的当前警告,因为它只警告构造函数未初始化的成员。

(并且由于这是一个已知问题,因此无需再次将其报告为错误。)

于 2012-12-22T11:46:13.477 回答
6

可以忽略这个警告吗?是的。

忽略这个警告是个好主意吗?依靠(*)

你应该向 gcc 提交错误吗?不(*)

(*)

  • default构造函数实际上初始化m_bar就好了,你可以测试一下
  • g++ 没有得到那个有点奇怪
  • 您选择了非常详细的警告设置
  • 警告不是关于你的代码的正确性,而是关于风格
  • 您无法更正此问题并保留 Foo 的默认构造函数和 Bar 的自定义构造函数

man g++, 部分 -Weffc++

警告违反 Scott Meyers 的 Effective C++ 书中的以下样式指南:

  • 第 11 项:为具有动态分配内存的类定义复制构造函数和赋值运算符。
  • 第 12 项:在构造函数中更喜欢初始化而不是赋值。
  • 第 14 条:在基类中使析构函数为虚拟。
  • 第 15 项:让“operator=”返回对 *this 的引用。
  • 第 23 条:当你必须返回一个对象时,不要试图返回一个引用。

还要警告违反 Scott Meyers 的《更有效的 C++》一书中的以下样式指南:

  • 第 6 项:区分递增和递减运算符的前缀和后缀形式。
  • 第 7 项:永远不要重载“&&”、“││”或“,”。

选择此选项时,请注意标准库头文件并不遵守所有这些准则。

于 2012-12-22T12:02:55.823 回答