2

假设我有一个类/结构,其中有一个联合......类似于:

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 来自'大括号封闭的初始化列表'的转换”。第二个不编译“不能省略围绕子对象初始化的大括号......”

我尝试了其他一些案例,但似乎无法让它跨多个平台编译。

4

2 回答 2

4
于 2013-08-23T20:23:14.787 回答
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被调用的值和 4 个被调用的类型的单独值的联合,以及(intr后4个都占用相同的空间)。AS32abcd

大概,你的想法是:

struct Box2
{
    union
    {
        AS128 intr;
        struct
        {
            AS32  a;
            AS32  b;
            AS32  c;
            AS32  d;
        } s;
    };
};

这使用了 C11 的匿名成员功能(在 ISO/IEC 9899:2011 的前言中列出作为与 C99 相比的新功能)。 [这个问题现在已经修复,或多或少地反映了这个符号(使用匿名结构)。请注意,您不能直接指定匿名工会成员,因此s至少上面是一个好主意。可以使用没有的结构s,但我认为除非你可以指定它,否则你不能初始化结构——你只能指定联合的命名元素。]

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

struct Box1 b1 = { { 1234 } };

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

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

struct Box1 b2 = { { .a = 1234 } };

请注意,您不能这样做:

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

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

使用第二个变体struct Box2

struct Box2 b4 = { { .s = { .a = 32, .b = 65, .c = 48, .d = 97 } } };

示例代码

AS128对和AS32类型名称使用有趣的类型。

typedef long AS128;
typedef char AS32;

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

struct Box2
{
    union
    {
        AS128 intr;
        struct
        {
            AS32  a;
            AS32  b;
            AS32  c;
            AS32  d;
        } s;
    };
};

struct Box1 b1a = { { 1234 } };
struct Box1 b1b = { { .intr = 1234 } };
struct Box1 b1c = { { .a = 32 } };
//struct Box1 b1d = { { .b = 29, .c = 31 } }; // Invalid double initialization
//error: initialized field overwritten [-Werror=override-init]

struct Box2 b2a = { { 1234 } };
struct Box2 b2b = { { .intr = 1234 } };
struct Box2 b2c = { { .s = { .a = 29, .b = 30, .c = 31, .d = 32 } } };
于 2013-08-23T23:25:01.457 回答