如何使用匿名结构/联合编译C代码?

sol*_*ent 64 c c++ struct anonymous unions

我可以用c ++/g ++做到这一点:

struct vec3 { 
    union {
        struct {
            float x, y, z;
        }; 
        float xyz[3];
    }; 
};
Run Code Online (Sandbox Code Playgroud)

然后,

vec3 v;
assert(&v.xyz[0] == &v.x);
assert(&v.xyz[1] == &v.y);
assert(&v.xyz[2] == &v.z);
Run Code Online (Sandbox Code Playgroud)

将工作.

如何使用gcc在c中执行此操作?我有

typedef struct {
    union {
        struct {
            float x, y, z;
        };
        float xyz[3];
    };
} Vector3;
Run Code Online (Sandbox Code Playgroud)

但我特别是周围都有错误

line 5: warning: declaration does not declare anything
line 7: warning: declaration does not declare anything
Run Code Online (Sandbox Code Playgroud)

小智 50

根据http://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields

-fms-extensions 将启用您(和我)想要的功能.

  • gcc 4.6还使用`-std = c1x`和gcc 4.7+以及`-std = c11'启用此功能 (11认同)

R S*_*hko 32

(这个答案适用于C99,而不是C11).

C99没有匿名结构或联合.你必须给它们命名:

typedef struct {
    union {
        struct {
            float x, y, z;
        } individual;
        float xyz[3];
    } data;
} Vector3;
Run Code Online (Sandbox Code Playgroud)

然后在访问它们时必须使用该名称:

assert(&v.data.xyz[0] == &v.data.individual.x);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,因为您的顶级结构有一个类型为union的项,您可以简化:

typedef union {
    struct {
        float x, y, z;
    } individual;
    float xyz[3];
} Vector3;
Run Code Online (Sandbox Code Playgroud)

现在访问数据变为:

assert(&v.xyz[0] == &v.individual.x);
Run Code Online (Sandbox Code Playgroud)

  • C11加了他们. (4认同)
  • GNU Dialect of C支持匿名结构和联合. (3认同)

hda*_*nte 25

新的C11标准将支持匿名结构和工会,参见2011年4月草案的前言第6段.

http://en.wikipedia.org/wiki/C1X

奇怪的是,gcc和clang现在都支持C89和C99模式下的匿名结构和联合.在我的机器上没有出现警告.

  • `-pedantic`标志会抓住这个. (5认同)

Ion*_*ham 11

也可以始终执行以下操作:

typedef struct
{
    float xyz[0];
    float x, y, z;
}Vec3;
Run Code Online (Sandbox Code Playgroud)

零长度数组不分配任何存储空间,只是告诉C"指向下一个声明的内容." 然后,您可以像任何其他数组一样访问它:

int main(int argc, char** argv)
{
    Vec3 tVec;
    for(int i = 0; i < 3; ++i)
    {
        tVec.xyz[i] = (float)i;
    }

    printf("vec.x == %f\n", tVec.x);
    printf("vec.y == %f\n", tVec.y);
    printf("vec.z == %f\n", tVec.z);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果:

vec.x == 0.000000
vec.y == 1.000000
vec.z == 2.000000
Run Code Online (Sandbox Code Playgroud)

如果您想要更加偏执,您可以手动指定数据打包策略以适合您的平台.

  • 其实我在说谎 如果将float [0](gnu99)更改为float [](c99)-它不会编译,因为变量数组必须位于struct的末尾,在这种情况下,它没有任何意义。所以是float [0]。 (2认同)

AnT*_*AnT 8

匿名联合是C++语言的一个特性.C语言没有匿名联盟.

C和C++都不存在匿名结构.

您在问题中提出的声明可能会使用GCC C++编译器进行编译,但它只是一个特定于编译器的扩展,它与标准C和标准C++无关.

最重要的是,无论你如何实现它,C语言和C++语言都不能保证你的断言能够成立.