工会内的工会
在C语言中,是否可以在另一个联合体中定义一个联合体?如果不是,为什么不可能?或者如果可以的话可以用在哪里?
In C, is it possible to define a union within another union? If no, why is it not possible? Or if yes, where can it be used?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
假设您要定义:
其中
sometype
是由您正在使用的库定义的typedef
。如果库碰巧将其实现为联合类型,那么这将是联合中的联合,并且这是有意义的,因为您不能(从良好的设计角度来看)违反库类型的封装。Suppose you want to define:
where
sometype
is atypedef
defined by a library you're using. If the library happened to implement it as a union type, then this would be a union within a union, and it would make sense because you can't (from a good design standpoint) violate the encapsulation of the library's type.是的,这是可能的,而且很有用。原因与 Y 中的 X 对 X 和 Y 的许多值有用的原因相同:组合性。程序是通过将微小的组件组装成小组件、组装成更大的组件、组装成巨大的组件……有时,一堆联合体恰好组装成一个联合体,那又怎样?
R..的答案显示了一个在幕后发生这种情况的示例:它只是碰巧联合成员类型之一是联合,但除非您查看库实现,否则您不知道这一点。
编辑 但是,请注意,可区分联合的常见习惯用法(其中联合的每个成员都是一个结构,其第一个字段是包含标签的整型类型)不会扩展到嵌套联合。也就是说,以下是常见的、符合标准的 (N1256 §6.5.2.3.5) 在 C 中实现可区分联合:
如果您有一个
union object
对象x
,您始终可以将其标签读取为x.generic.tag
(或x.bignum.tag
或任何其他),无论实际分配给对象的是什么。通过为对象使用唯一的标签(鉴别器)。以下定义是合法的,但没有用,因为您不能仅读取
union level2
对象的第一个字段来获取标记:如果union level2
对象被编写为union number
,必须通过number
成员读取其标签,否则必须通过generic
或成员读取其标签字符串
成员。如果通过错误的成员进行访问在每个现有的实现上都有效,但它不符合标准,我不会感到惊讶。Yes, it's possible, and useful. The reason is the same reason X within Y is useful for many values of X and Y: compositionality. Programs are built by assembling tiny components into small components into larger components into huge components into... Sometimes a bunch of unions happen to be assembled into a union, and so what?
R..'s answer shows an example where this happens behind the scenes: it just happens that one of the union member types is a union, but you don't know that unless you look at the library implementation.
EDIT However, note that the common idiom for discriminated unions where each member of the union is a structure whose first field is an integral type containing a tag does not extend to nested unions. That is, the following is a common, standard-compliant (N1256 §6.5.2.3.5) implementation of discriminated unions in C:
If you have an
union object
objectx
, you can always read its tag asx.generic.tag
(orx.bignum.tag
or any of the others), no matter what was actually assigned to the object. By using unique tags (discriminators) for the objects.The following definition is legal, but not useful as you cannot just read the first field of a
union level2
object to get the tag: if aunion level2
object was written as aunion number
, you have to read its tag through thenumber
member, and otherwise you have to read its tag through thegeneric
orstring
member. I wouldn't be surprised if accessing through the wrong member worked on every now existing implementation, but it is not standard-compliant.是的,这是可能的。但我倾向于坚持永远不要使用工会的建议。工会是正确答案的情况很少。我怀疑在任何情况下,包含工会的工会都是一个好主意。
Yes it is possible. But I'd tend to stick with the advice of never use unions. The number of situations where unions are the right answer are very small. I suspect there is no situation where a union containing a union is a good idea.
是的,这是可能的。我想不出如何很好地利用我的头顶,尽管很容易想出一个人为的例子。
Yes, it is possible. I can't think of a good use of the top of my head, although it would be easy to come up with a contrived example.
是的,一个联合可能包含另一个联合:
不过,我想不出它会有用(甚至是可取)的情况。
Yes, a union may contain another union:
I can't think of a situation where it would be useful (or even desirable), though.