【问题标题】:Union initialization in C++ and CC++ 和 C 中的联合初始化
【发布时间】:2012-07-18 08:01:28
【问题描述】:

我已经在定义为的头文件中构建了一个使用常量的工作 C 库

typedef struct Y {
  union {
    struct bit_field bits;
    uint8_t raw[4];
  } X;
} CardInfo;

static const CardInfo Y_CONSTANT = { .raw = {0, 0, 0, 0 } };

我知道 .raw 初始化器是仅限 C 的语法。

如何定义带有联合的常量,以便在 C 和 C++ 中使用它们。

【问题讨论】:

  • 你确定混合模式标签吗?
  • C++ 不是通过第一个元素初始化unions 吗? IE。 static const Y_CONSTANT = {{0,0,0,0}};
  • @YePhIcK 然后它会给出关于缺少大括号的额外警告。
  • @Alex - 我刚刚尝试了我的代码,它构建得很好,没有错误/警告。你确定你使用的是双括号吗? typedef struct Y { union { struct bit_field bits; uint8_t 原始[4]; } X; } 卡片信息;静态常量 CardInfo Y_CONSTANT = {{0, 0, 0, 0 } };
  • 这是正确的,语言就是这样——你可以初始化并集的第一个元素,并且只能初始化第一个

标签: c++ c initialization unions c++03


【解决方案1】:

我遇到了同样的问题。对于 C89,以下是正确的:

使用 C89 风格的初始化器,结构成员必须在 声明的顺序,并且只能是联合的第一个成员 初始化

我在以下位置找到了这个解释: Initialization of structures and unions

【讨论】:

    【解决方案2】:

    我相信 C++11 允许您像这样编写自己的构造函数:

    union Foo
    {
        X x;
        uint8_t raw[sizeof(X)];
    
        Foo() : raw{} { }
    };
    

    这默认初始化类型为Foo 的联合与活动成员raw,它的所有元素都初始化为零。 (在 C++11 之前,无法初始化不是完整对象的数组。)

    【讨论】:

    • @Alex:不,当然不是。但幸运的是,该结构将 layout-compatible 与类似声明的 C 结构...
    • 啊,我明白了,所以您想建议在正确的位置使用 #ifdef __cplusplus 以使该头文件可包含。啊,这可能会变得更加模糊。
    • 警告:添加构造函数会删除 POD,这在与联合进行内存访问时通常是可取的。
    • @Offirmo C++11 引入了一个新术语 standard-layout class ,允许有构造函数;许多在 C++03 中需要 POD 的情况现在只需要标准布局。 (POD 现在被定义为标准布局加上其他一些保证)。
    【解决方案3】:

    我决定选择以下路径。

    • 不要使用.member初始化。
    • 不要使用static const struct Foobar初始化成员

    改为声明全局变量:

    extern "C" {
      extern const struct Foobar foobar;
    }
    

    并在全局部分中对其进行初始化:

    struct Foobar foobar = { 0, 0, 0, 0 };
    

    我没有使用现代 ANSI C99 语法来干扰 C++ 编译器,而是让链接器完成对 C 符号进行解构的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-23
      • 2021-10-23
      • 2021-04-09
      • 1970-01-01
      • 2013-11-04
      • 2018-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多