如何使用匿名结构/联合编译 C 代码?
我可以在 c++/g++ 中执行此操作:
struct vec3 {
union {
struct {
float x, y, z;
};
float xyz[3];
};
};
然后,
vec3 v;
assert(&v.xyz[0] == &v.x);
assert(&v.xyz[1] == &v.y);
assert(&v.xyz[2] == &v.z);
就可以了。
如何用 gcc 在 c 中做到这一点?我有
typedef struct {
union {
struct {
float x, y, z;
};
float xyz[3];
};
} Vector3;
但是我到处都有错误,特别是
line 5: warning: declaration does not declare anything
line 7: warning: declaration does not declare anything
I can do this in c++/g++:
struct vec3 {
union {
struct {
float x, y, z;
};
float xyz[3];
};
};
Then,
vec3 v;
assert(&v.xyz[0] == &v.x);
assert(&v.xyz[1] == &v.y);
assert(&v.xyz[2] == &v.z);
will work.
How does one do this in c with gcc? I have
typedef struct {
union {
struct {
float x, y, z;
};
float xyz[3];
};
} Vector3;
But I get errors all around, specifically
line 5: warning: declaration does not declare anything
line 7: warning: declaration does not declare anything
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
根据 http://gcc.gnu.org/onlinedocs/gcc /Unnamed-Fields.html#Unnamed-Fields
-fms-extensions
将启用您(和我)想要的功能。according to http://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields
-fms-extensions
will enable the feature you (and I) want.(此答案适用于 C99,不适用于 C11)。
C99 没有匿名结构或联合。你必须给它们命名:
然后你必须在访问它们时使用名称:
在这种情况下,因为你的顶级结构有一个联合类型的单个项目,你可以简化这一点:
并且访问数据现在变成:
(This answer applies to C99, not C11).
C99 does not have anonymous structures or unions. You have to name them:
And then you have to use the name when accessing them:
In this case, because your top level structure has a single item of type union, you could simplify this:
and accessing the data now becomes:
新的 C11 标准将支持匿名结构和联合,请参阅 2011 年 4 月草案的前言第 6 段。
http://en.wikipedia.org/wiki/C1X
奇怪的是 gcc 和clang 现在支持 C89 和 C99 模式下的匿名结构和联合。在我的机器上没有出现警告。
The new C11 standard will support anonymous structures and unions, see foreword paragraph 6 of the April 2011 draft.
http://en.wikipedia.org/wiki/C1X
The strange part is that both gcc and clang now support anonymous structures and unions in C89 and C99 mode. In my machine no warnings appear.
人们还可以始终执行以下操作:
零长度数组不分配任何存储,只是告诉 C“指向声明的下一个事物是什么”。然后,您可以像访问任何其他数组一样访问它:
结果:
如果您想更加偏执,您可以手动指定数据打包策略以适合您的平台。
One can also always do the following:
The zero-length array doesn't allocate any storage, and just tells C to "point to whatever the next thing declared is." Then, you can access it just like any other array:
Result:
If you want to be extra paranoid, you can manually specify the data packing strategy to suit your platform.
匿名联合是 C++ 语言的一个特性。 C语言没有匿名联合。
C 和 C++ 中都不存在匿名结构。
您在问题中提出的声明可能会使用 GCC C++ 编译器进行编译,但它只是一个特定于编译器的扩展,与标准 C 或标准 C++ 无关。
最重要的是,无论您如何实现它,C 语言或 C++ 语言都不能保证您的断言成立。
Anonymous unions is a feature of C++ language. C language has no anonymous unions.
Anonymous structs don't exist in neither C nor C++.
The declaration you presented in your question might compile with GCC C++ complier, but it would be just a compiler-specific extension, which has nothing to do with neither standard C nor standard C++.
On top of that, regardless of how you implement it, neither C nor C++ language guarantees that your assertions will hold.
我可以在 GCC 中执行此操作而不发出警告
I can do this in GCC without warning
C 中也不支持匿名联合。
另请注意,如果您这样声明:
Doing
是一种未定义的行为。您只能访问最后分配的工会成员。在您的情况下,使用联合是错误的并且是糟糕的编码实践,因为它依赖于标准中未指定的许多事情(填充...)。
在 C 中,你会更喜欢这样的东西:
如果你不想使用 v[x] 你可能会考虑:
Anonymouse unions are nor supported in C.
Also note that if you declare it this way:
Doing
Is an undefined behaviour. You can only access the last assigned union member. In your case, using an union is wrong and bad coding practice as it's dependent on many things that are not specified in the standard (padding...).
In C you will prefer something like this:
And if you don't want to use v[x] you might consider:
C 的 GNU 方言支持匿名结构/联合,但默认情况下 GCC 使用某种标准 C 进行编译。要使用 GNU 方言,请在命令行上输入“-std=gnu99”。
The GNU dialect of C supports anonymous structs/unions, but by default GCC compiles using some kind of standard C. To use the GNU dialect, put "-std=gnu99" on the command line.
未识别的结构成员不是 ANSI/ISO C99 标准解释了这一点,但我发现一件有趣的事情发生了,在 GNU C 编译器 2.xx 版本的某些端口上,使用未识别的结构成员可以工作,它会找到它们,不会说类似“ x 不是 union\struct y 的成员,x 是什么?”,其他时候,它是 ol'“x 未定义”,“x 不是 struct 的成员”,见鬼,我发誓我看到了一个“指向未知的指针” ” 不久前,因为这个。
因此,在专业上,我会与其他人一起解决这个问题,只是为 struct\union 成员提供一个标识符,或者在 UNION 的情况下,仔细地重新排列代码,以便 union 最终成为已识别结构的已识别成员,以及嵌入到原始联合体的未识别结构中,成为已识别结构的成员,并与已识别的联合体成员谨慎使用。
但在这些情况下,如果后一种方法不是可行的替代品,我只会给讨厌的结构一个标识符并继续。
Unidentified struct members not being ANSI/ISO C99 standard explains this, but I find a funny thing happens, on some ports of GNU C Compiler 2.x.x versions, using undentified struct members works, it finds them, doesn't say stuff like "x is not a member of union\struct y, what is x?", other times, it's the ol' "x is undefined", "x is not a member of struct", hell I swear I saw a "pointer to unknown" once a while back, due to this.
So I, professionally would go with everyone else on this and just ether give the struct\union member a identifier, or in the case of UNIONs, carefully rearrange the code so the union ends up an identified member of a identified structure and the members that were embedded in the unidentified structure of the original union, become members of the identified structure and are carefully used with the identified union member.
But in those cases were the latter method would not be a workable substitute, I would just give the annoynous structure an identifier and move on.
我可以建议一个有趣的解决方法,以避免结构中出现过多的字段。建议对简单命名的定义发出警告,因为它可能会产生冲突。
您可以像这样访问结构:
最后,这将是与 C99 兼容的多类型联合:
I can suggest an interesting workaround in order to avoid too much fields within the structure. One is advised to warn about simply named defines, as it could create conflicts.
You could access the structure like this:
To finish, this would be a multi type union compatible with C99: