【问题标题】:struct uninitialization issue in c++C ++中的结构未初始化问题
【发布时间】:2020-09-23 06:05:55
【问题描述】:

我有以下三个结构定义,对于SA, SBad, SC,我简化了名称和成员来说明问题。

 struct SA {
     int snap;
 };

 template <int W> class VString
 {
     char data[W];
   public:
     VString() { }
 };

 struct SBad {
     VString<9> s;
     int i;
 };

 struct SC {
     int inst;
 };

我有一个包含结构来保存来自网络的数据,它由上述结构组成:

 struct S {
     std::vector<SA>           m_a;
     SBad                      m_bad;
     std::vector<SC>           m_c;
 };

并且在代码中我需要经常重置结构,使用:

// data member
S m_s;
// member function
void clear() {
   m_s.m_bad   = {};
}

我使用的是 gcc 版本 7.3.1。使用调试版本,这可以正常工作,使用发布版本,它会失败:

error: '<anonymous>' is used uninitialized in this function [-Werror=uninitialized]

gcc 标志是:

-std=c++11 -O3 -Werror -Wall

为什么会出现这个错误,这是一种将数据初始化为零的定义方式,对吧? 如果我改为:

void clear() {
    SA sa{};
    m_s.a = sa;
    m_s.b = {};
    ...
}

相反,发布构建会成功。

更新:

我创建了一个minimum working test case 来显示问题。

【问题讨论】:

  • 请提供一个我们可以看到错误的最小示例
  • 只包含数据成员,没有函数成员。
  • 请附上minimal reproducible example 和完整的错误信息
  • cannot reproduce。您发布的代码中没有任何“使用”或任何“匿名”。该错误可能是由您未发布的代码引起的
  • 好的,我正在为此做一个测试用例。

标签: c++11 gcc struct initialization list-initialization


【解决方案1】:

您只能将花括号初始化与“聚合”一起使用。引用标准:

聚合是一个数组或一个类(第 9 条)没有用户声明的构造函数 (12.1),没有私有或受保护的非静态 数据成员(第 11 条),无基类(第 10 条),无虚拟 函数 (10.3)。

...

当一个聚合被初始化时,初始化器可以包含一个 由大括号括起来的组成的初始化子句,以逗号分隔 聚合成员的初始化子句列表,书面 以递增的下标或成员顺序。如果聚合包含 子聚合,这个规则递归地应用到 子聚合。

在您的情况下,SBad 不是聚合,因为 VString 类型的 SBad::s 不是聚合,因为您为 VString 定义了构造函数.要让您的代码正常工作,请删除 VString 的构造函数:

 template <int W> class VString {
     char data[W];
 };

在这里试试:https://godbolt.org/z/TTonr6

【讨论】:

  • 谢谢,你是对的,问题出在这个 ctor 上,但是 gcc 给出了其他领域的错误,这很容易误导......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多