假设我有一个带有单个联合的类/结构...类似于:
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没有已知转换”。第二个不编译“不能省略围绕子对象初始化的大括号......”
我已经尝试过其他一些案例,似乎无法在多个平台上进行编译。
答案 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中,您还需要使用Box
将typedef
声明为类型,或将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}}和名为intr
,AS32
,a
的{{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 Box2
和struct Box2 b4 = { { .s = { .a = 32, .b = 65, .c = 48, .d = 97 } } };
类型名称使用有趣的类型。
AS128