联合初始化列表的正确格式是什么?

时间:2013-08-23 20:10:24

标签: c++ c initialization unions

假设我有一个带有单个联合的类/结构...类似于:

struct Box { union { AS128 intr; struct { AS32 a, b, c, d; }; }; };

为这种数据类型执行初始化列表的正确方法是什么?

Box iMyBoxA = { 10, 10, 100, 100 };
Box iMyBoxB = ( Box ){ 10, 10, 100, 100 };

上面的“A”选项在许多情况下都有效,但不是完全可移植的......给出错误“来自'大括号括号初始化列表''的参数1没有已知转换”。第二个不编译“不能省略围绕子对象初始化的大括号......”

我已经尝试过其他一些案例,似乎无法在多个平台上进行编译。

2 个答案:

答案 0 :(得分:4)

一个联盟一次只能拥有一个成员,因此只用一个值初始化它。

您可以使用Box iMyBoxA = { value };初始化第一个列出的联盟成员,或Box iMyBoxA = { .name = value };按名称初始化特定成员。

一些注意事项:

您的代码在联合声明后缺少分号;它应该是:

struct Box { union { AS128 intr; AS32 a, b, c, d; }; };

由于你在struct中有一个union,你应该为初始化器使用两组大括号:

Box iMyBoxA = { { value } };

允许使用一组大括号的语法,但可能会从编译器中引出警告。

指定的初始值设定项(初始化程序中的成员名称)是C 1999功能。这个问题用C和C ++标记。 C ++编译器可能会也可能不会接受指定的初始化程序。在C中,您还需要使用Boxtypedef声明为类型,或将Box iMyBoxA…更改为struct Box iMyBoxA…

在C中,匿名工会在C 2011中是新的。

答案 1 :(得分:3)

问题中结构和联合定义的原始版本是:

struct Box { union { AS128 intr; AS32 a, b, c, d; } };

这有点不寻常。假设定义了AS128和AS32类型,则它等同于:

struct Box1  // Renamed for convenience of testing
{
    union
    {
        AS128 intr;
        AS32  a;
        AS32  b;
        AS32  c;
        AS32  d;
    };
};

也就是说,它是名为AS128的{​​{1}}和名为intrAS32a的{​​{1}}类型的4个独立值的并集}和b(后者4都占据相同的空间)。

据推测,你的想法是:

c

这使用了C11的匿名成员功能(在ISO / IEC 9899:2011的前言中列为与C99相比的新功能)。 [现在已经修复了这个问题,或多或少反映了这种表示法(使用匿名结构)。请注意,您无法直接指定匿名工会成员,因此上面的d至少是一个好主意。可以使用没有struct Box2 { union { AS128 intr; struct { AS32 a; AS32 b; AS32 c; AS32 d; } s; }; }; 的结构,但我不认为你可以初始化结构,除非你可以指定它 - 你只能指定一个联合的命名元素。]

使用第一个变体(s),您可以初始化没有名称的第一个成员(s成员):

struct Box1

外支撑用于结构;内括号用于(匿名)联合。

或者您可以使用指定的初始化程序指定要初始化的成员:

AS128 intr;

请注意,您无法执行以下操作:

struct Box1 b1 = { { 1234 } };

编译器发出警告(参见下面的示例代码)。

使用嵌套结构的第二个变体(struct Box1 b2 = { { .a = 1234 } }; ),您仍然可以使用未指定的初始值设定项或指定的初始值设定项,但这次,您可以指定结构的所有4个成员:

struct Box1 b3 = { { .a = 1234, .b = 2341 } };

示例代码

struct Box2struct Box2 b4 = { { .s = { .a = 32, .b = 65, .c = 48, .d = 97 } } }; 类型名称使用有趣的类型。

AS128