【问题标题】:gcc: lack of warning about order of initialization in constructorsgcc:缺乏关于构造函数中初始化顺序的警告
【发布时间】:2012-05-11 09:42:22
【问题描述】:

gcc 是否应该警告 C 类中成员变量 ab 的初始化顺序?基本上,对象 b 已初始化,它的构造函数在对象 A 之前调用。这意味着 b 使用未初始化的 a

#include <iostream>

using namespace std;

class A
{
    private:
        int x;
    public:
        A() : x(10) { cout << __func__ << endl; }
        friend class B;
};

class B
{
    public:
        B(const A& a) { cout << "B: a.x = " << a.x << endl; }
};

class C
{
    private:
        //Note that because b is declared before a it is initialized before a
        //which means b's constructor is executed before a.
        B b;
        A a;

    public:
        C() : b(a) { cout << __func__ << endl; }
};

int main(int argc, char* argv[])
{
    C c;
}

来自 gcc 的输出:

$ g++ -Wall -c ConsInit.cpp 
$ 

【问题讨论】:

  • 你可以告诉它警告你。标志是 -Wreorder,它通过 -Wall 开启。
  • 您应该确保使用-Wall -Werror -Wextra -pedantic-errors 进行编译。代码将无法编译,因为 gcc 会警告您正在使用未初始化的
  • @bamboon:你确定吗?代码在这里编译得很好。
  • 看起来你的order初始化没问题。只是你没有初始化你的一个成员然后使用它。
  • 我没有从 gcc 或 clang 收到最高警告级别的警告,这有点奇怪。您应该向相应的跟踪器提交错误。

标签: c++ gcc initialization initializer-list


【解决方案1】:

为了使这成为初始化问题的顺序,您需要实际尝试以错误的顺序初始化子对象:

public:
    C() : a(), b(a) { cout << __func__ << endl; } 
          ^^^ this is attempted initialization out of order

正如所写,唯一的违规行为是在对象 (C::a) 的生命周期开始之前将引用(B::B(const A&amp;) 的参数)绑定到对象 (C::a),这是一个非常值得怀疑的违规行为,因为获取指向 a 的指针会实际上是合法的,低于 $3.8[basic.life]/5 (并且在 a 的初始化之前取消引用它是 UB)

【讨论】:

  • 我认为你是对的。正如您所提到的,从技术上讲,它与初始化顺序没有任何关系。
猜你喜欢
  • 2012-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 2010-11-17
相关资源
最近更新 更多