工会内的工会

发布于 2024-09-25 02:50:16 字数 60 浏览 4 评论 0原文

在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ゝ偶尔ゞ 2024-10-02 02:50:16

假设您要定义:

union myun {
  int x;
  sometype y;
};

其中 sometype 是由您正在使用的库定义的 typedef。如果库碰巧将其实现为联合类型,那么这将是联合中的联合,并且这是有意义的,因为您不能(从良好的设计角度来看)违反库类型的封装。

Suppose you want to define:

union myun {
  int x;
  sometype y;
};

where sometype is a typedef 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.

殤城〤 2024-10-02 02:50:16

是的,这是可能的,而且很有用。原因与 Y 中的 X 对 X 和 Y 的许多值有用的原因相同:组合性。程序是通过将微小的组件组​​装成小组件、组装成更大的组件、组装成巨大的组件……有时,一堆联合体恰好组装成一个联合体,那又怎样?

R..的答案显示了一个在幕后发生这种情况的示例:它只是碰巧联合成员类型之一是联合,但除非您查看库实现,否则您不知道这一点。


编辑 但是,请注意,可区分联合的常见习惯用法(其中联合的每个成员都是一个结构,其第一个字段是包含标签的整型类型)不会扩展到嵌套联合。也就是说,以下是常见的、符合标准的 (N1256 §6.5.2.3.5) 在 C 中实现可区分联合:

struct generic {
    unsigned tag;
};
struct smallnum {
    unsigned tag; /*always TAG_SMALLNUM*/
    unsigned value;
};
struct bignum {
    unsigned tag; /*always TAG_BIGNUM*/
    size_t length;
    unsigned *p;
};
struct string {
    unsigned tag; /*always TAG_STRING*/
    size_t length;
    char *p;
};
union number {
    struct bignum bignum;
    struct smallnum smallnum;
};
union object {
    struct generic generic;
    struct bignum bignum;
    struct smallnum smallnum;
    struct string string;
};

如果您有一个 union object 对象 x,您始终可以将其标签读取为x.generic.tag (或 x.bignum.tag 或任何其他),无论实际分配给对象的是什么。通过为对象使用唯一的标签(鉴别器)。

以下定义是合法的,但没有用,因为您不能仅读取 union level2 对象的第一个字段来获取标记:如果 union level2 对象被编写为union number,必须通过number成员读取其标签,否则必须通过generic成员读取其标签字符串 成员。如果通过错误的成员进行访问在每个现有的实现上都有效,但它不符合标准,我不会感到惊讶。

union level2 {
    struct generic generic;
    union number number;
    struct string string;
};

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:

struct generic {
    unsigned tag;
};
struct smallnum {
    unsigned tag; /*always TAG_SMALLNUM*/
    unsigned value;
};
struct bignum {
    unsigned tag; /*always TAG_BIGNUM*/
    size_t length;
    unsigned *p;
};
struct string {
    unsigned tag; /*always TAG_STRING*/
    size_t length;
    char *p;
};
union number {
    struct bignum bignum;
    struct smallnum smallnum;
};
union object {
    struct generic generic;
    struct bignum bignum;
    struct smallnum smallnum;
    struct string string;
};

If you have an union object object x, you can always read its tag as x.generic.tag (or x.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 a union level2 object was written as a union number, you have to read its tag through the number member, and otherwise you have to read its tag through the generic or string member. I wouldn't be surprised if accessing through the wrong member worked on every now existing implementation, but it is not standard-compliant.

union level2 {
    struct generic generic;
    union number number;
    struct string string;
};
—━☆沉默づ 2024-10-02 02:50:16

是的,这是可能的。但我倾向于坚持永远不要使用工会的建议。工会是正确答案的情况很少。我怀疑在任何情况下,包含工会的工会都是一个好主意。

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.

花开雨落又逢春i 2024-10-02 02:50:16

是的,这是可能的。我想不出如何很好地利用我的头顶,尽管很容易想出一个人为的例子。

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.

絕版丫頭 2024-10-02 02:50:16

是的,一个联合可能包含另一个联合:

union foo {
  int x;
  double y;
  union bar {
    char blah[10];
    char *blurga;
  } bletch;
};

不过,我想不出它会有用(甚至是可取)的情况。

Yes, a union may contain another union:

union foo {
  int x;
  double y;
  union bar {
    char blah[10];
    char *blurga;
  } bletch;
};

I can't think of a situation where it would be useful (or even desirable), though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文