在C1X中初始化匿名结构或联合

jmu*_*muc 19 c standards structure anonymous c11

我有以下问题:根据当前的C1X草案,匿名结构(或联合)如何正确初始化?这是合法的:

struct foo {
    int a;
    struct {
        int i;
        int j;
    };
    int b;
};

struct foo f = { 1, 2, 3, 4 };
struct foo g = { 1, { 2 }, 3 };
Run Code Online (Sandbox Code Playgroud)

在海湾合作委员会,g.j == 0g.b == 3同时在TCC g.j == 3g.b == 0.目前的草案说:

"[...]结构和联合类型的对象的未命名成员不参与初始化.结构对象的未命名成员即使在初始化之后也具有不确定的值."

这真的可以吗?是不是

struct foo h = { 0 };
Run Code Online (Sandbox Code Playgroud)

应该将所有成员设置为0?

非常感谢!

更新:

由于匿名成员似乎只在混合结构/联合时有用,如何正确初始化它:

struct bar {
    int tag;
    union {
        double d;
        int i;
    };
};
Run Code Online (Sandbox Code Playgroud)

?这给出了gcc <4.6和icc 11中的错误,但是在gcc 4.6,icc 12,clang和tcc中有效:

struct bar a = { .tag = 1, .i = 42 };
Run Code Online (Sandbox Code Playgroud)

这会给clang和tcc带来错误,但是在gcc和icc中有效:

struct bar b = { .tag = 1, { .i = 42 } };
Run Code Online (Sandbox Code Playgroud)

第二个违反了标准吗?

Chr*_*oph 6

f并且h应该正确地初始化所有成员,i并且j将被视为struct foo(C1x6.7.2.1§13)的成员:

匿名结构或联合的成员被视为包含结构或联合的成员.

我不认为gcc的初始化g是正确的,考虑到C1x6.7.9§9:

除非另有明确说明,否则为了本子条款的目的,结构和联合类型的对象的未命名成员不参与初始化.

§20 - 处理子聚合 - 不包含与问题相关的明确声明,因此我最好的猜测是§9适用(但仅适用于聚合本身,而不适用于其成员!).

底线是匿名子聚合不作为单独的对象存在,即tcc的行为应该是正确的...

我对此问题采取的示例代码:

struct foo
{
    struct bar { int i; }; // (1) unnamed, but tagged, ie *not* anonymous
    struct { int j; };     // (2) unnamed, but anonymous
    struct { int k; } baz; // (3) named, but not tagged
};
Run Code Online (Sandbox Code Playgroud)

(1)不参与初始化,(2)初始化好像struct foo有一个名为的附加成员j,(3)初始化为常规子聚合.

如果我的解释是正确的,那么匿名结构只有在包含在一个联合中才有意义:结构中的匿名结构与包含其他成员的平面结构无法区分.