【问题标题】:What is the meaning of double curly braces initializing a C-struct?初始化C结构的双花括号是什么意思?
【发布时间】:2011-09-09 05:15:24
【问题描述】:

我目前正在使用旧版 C++ 代码,使用 gcc 2.9.X 成功编译。
我被要求将此遗留代码移植到 gcc 3.4.X。大多数错误都很容易纠正,但这个特殊的错误让我感到困惑。

上下文:

 struct TMessage 
   {
    THeader header;
    TData data;
   };

 struct THeader
   {
    TEnum myEnum;
    TBool validity;
   };

做了什么:

 const TMessage init = {{0}};

 /* Later in the code ... */
 TMessage message = init;

我的问题
{{}} 运算符的含义是什么?它是否将第一个字段(header)初始化为二进制 0 ?它是否将第一个结构(enum)的第一个字段初始化为(字面量)0?

我得到的 3.4.6 错误是 invalid conversion from 'int' to 'TEnum',带有一对或两对花括号。

如何在不使用 memset 的情况下将我的结构设置为一堆 0?

提前致谢。

【问题讨论】:

  • 为什么要将代码从旧版本的 gcc 移植到另一个旧版本的 gcc?
  • 在另一个平台上编译/链接/执行它。
  • 不了解 C++。在 C 语言中没有错误(也许你的编译器过于有帮助到了错误的地步)
  • 而且你真的不应该尝试编写多语言源文件。这比它的价值要付出更多的努力。选择一种语言(C 或 C++ ...或 D 或 Eiffel 或 Forth 或 ...)并坚持下去。
  • 正如我所说,这是遗留代码,我无权更改任何内容,除非在 3.4.6 中无法编译。否则我会同意你的看法;)

标签: c++ c struct


【解决方案1】:
  • 第一个大括号用于struct TMessage
  • 第二个大括号用于struct THeader
  • 零字面量用于TEnum myEnum

在这种情况下,您将使用int 0 初始化TEnum,即incompatible conversion

所以你必须像这样添加转换:

const TMessage init = {{TEnum(0)}};

在 C/C++ 中,如果您使用 partially initialized 结构或数组(只有一些第一个字段/元素),其余部分将由 default constructor 初始化(这是原始类型的零初始化)。 如果没有默认构造函数或者构造函数声明为private,则会出现编译错误。

【讨论】:

  • 其余部分总是初始化为零是不正确的。正如我在对@Autopulated 答案的评论中发布的那样,它们将被值初始化。例如,如果其中一个成员属于具有默认构造函数的类类型,则将调用该构造函数。
【解决方案2】:

它将POD结构的所有字段初始化为0。

理由:

const SomeStruct init = {Value};

将 SomeStruct 的第一个字段初始化为 Value,将结构的其余部分初始化为零(我忘记了标准中的部分,但它在某处)

因此:

const SomeOtherStruct init = {{Value}};

将结构的第一个字段(其中结构的第一个字段本身是 POD 结构)的第一个字段初始化为 Value,第一个字段的其余部分初始化为零,结构的其余部分初始化为 0。

此外,这只是不起作用,因为 c++ 禁止将 int 隐式转换为枚举类型,因此您可以这样做:

const SomeOtherStruct init = {{TEnum(0)}};

【讨论】:

  • 所以你是说 const TMessage init = {{myEnumFirstValue}}; 会初始化我的枚举,然后所有其他字段都为 0 ?它编译成功,我现在关心运行时。无论如何谢谢!
  • 标准的相关部分是 8.5.1.7: 如果列表中的初始化器少于聚合中的成员,则每个未显式初始化的成员都应进行值初始化。
  • 谢谢@Space,还有@Isaac。
  • 据我所知,值初始化总是意味着在这种情况下默认构造,这意味着简单类型设置为 0。 (我很确定其他一切最终都为零......)
  • @Autopulated:如果不存在默认构造函数,则所有非静态成员(也适用于基类)都是值初始化的(它基本上以递归方式工作)。对于原始类型,值初始化意味着零初始化(这是递归的终止)。
【解决方案3】:

你可以把它想象成一个多维数组(如果有帮助的话)。然后,您使用该命令将两个维度重置为 0。这是有效的,因为(我假设)结构中的值可以取 0 作为值。

【讨论】:

  • 谢谢!不过,我错过了每个 other 字段都被初始化为 0 的事实。
猜你喜欢
  • 1970-01-01
  • 2020-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多