【问题标题】:How to initialize anonymous composite types in C如何在 C 中初始化匿名复合类型
【发布时间】:2014-01-30 07:20:41
【问题描述】:

鉴于类似(改编自another post):

struct {
    union {
        struct {
            float x, y, z;
        };
        float xyz[3];
    };
    int a;
} v = { /* what goes here? */ };

如何将其初始化到位?我知道我必须为 xyz 成员使用指定的初始化程序,但如果我想要第一组成员,我是否必须这样做?

...

看看yet another post,它的例子只处理匿名结构,而不是联合,但我猜语法是

//...
} v = { someX, someY, someZ, someA };

它初始化联合的第一个变体的三个成员,然后是整个联合部分之后的int。是这样吗?

【问题讨论】:

    标签: c initialization c11


    【解决方案1】:

    匿名结构最早出现在 C11 标准中。

    6.7.2.1.13 声明:

    匿名结构或联合的成员被视为包含结构或联合的成员。如果包含结构或联合也是匿名的,这将递归地应用。

    考虑第 6.7.8 节中的示例,您有多种选择,包括非常冗长的选择:

    struct {
        union {
            struct {
                float x, y, z;
            };
            float xyz[3];
        };
        int a;
    } v = { .x = 1.0f, .y = 2.0f, .z = 3.0f, 2 };
    

    struct {
        union {
            struct {
                float x, y, z;
            };
            float xyz[3];
        };
        int a;
    } v = { .xyz[0] = 1.0f, .xyz[1] = 2.0f, .xyz[2] = 3.0f, .a = 2 };
    

    您的带有普通 {1.0f, 2.0f, 3.0f, 4} 的变体在 Wall 打开时会发出警告 warning: missing braces around initializerv = { {1.0, 2.0, 3.0}, 2 } 也会发出警告。所以我建议添加明确的字段描述。

    我在 gcc 4.8.1 上测试了这些初始化,并打开了 --std=c11 -Wall -pedantic。

    【讨论】:

    • 1- 您的意思是 c89,而不是 c98。 2-它不像你说的那样依赖于标准:首先,在旧标准中工作的任何初始化仍然在新标准中工作,其次,c11 没有添加任何新语法来初始化聚合。剩下两种方法,其中最新的方法是 15 年前标准化的。
    • 谢谢,已修复。当然 C90(或 C89 是早期的 ANSI 版本)不是 C98。
    • 直到 C11,C 才支持匿名复合;我现在不需要了解预标准版本(即 C89/90/99 的扩展)。
    • 我在这里问是因为 C11 标准(我检查过的草案)中的描述包含任何示例。顺便说一句,由于在初始化时不考虑匿名复合,我不确定你可以用冗余(?)大括号包围多个术语。 (您可以用多余的大括号将单个术语括起来。)
    • 嗯...很有启发性。我编辑了我的答案,关于您的更正,选择了更新的编译器和 c11 标准选项。
    【解决方案2】:
    struct A{
        union B{
            struct C {
                float x, y, z;
            } S;
            float xyz[3];
        } U;
        int a;
    };
    
    int main ()
    {
        struct A v = { .U.S.x = 0.0f, .U.S.y = 123.234f, .U.S.z= 123.3f };
        struct A w = { .U.xyz = {0.0f, 123.234f, 123.3f} };
    
        printf("\n %f %f %f  \n ",v.U.S.x, v.U.S.y ,v.U.S.z);
    }
    

    【讨论】:

    • 一个 C11 匿名组合既没有标签也没有成员名,这里的联合和内部结构都有。所以你的例子不适用。
    • 好的,我在 Linux 中使用 gcc 尝试了相同的代码,它可以工作
    • 你错过了我的意思。我问的是匿名structs 和unions,什么都没有 在你的例子中是匿名的!我在问如何使用指定来初始化而不
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    相关资源
    最近更新 更多