为了账号安全,请及时绑定邮箱和手机立即绑定

C / C ++中的并集大小

C / C ++中的并集大小

C++ C
BIG阳 2019-11-18 18:12:18
C / C ++中的并集大小是多少?它里面最大的数据类型的大小吗?如果是这样,如果联合的较小数据类型之一处于活动状态,编译器如何计算如何移动堆栈指针?
查看完整描述

3 回答

?
HUX布斯

TA贡献1876条经验 获得超6个赞

该标准回答了C ++标准9.5节或C99标准第6.5.2.3节第5段(或C11标准的第6段或C18标准的6.7.2.1节第16段)中的所有问题:


在联合中,最多可以在任何时间激活一个数据成员,即,最多可以在任何时间将一个数据成员的值存储在一个联合中。[注:为了简化并集的使用,做出了一项特殊保证:如果POD联合包含多个共享共同初始序列(9.2)的POD结构,并且此POD联合类型的对象包含以下一个: POD结构,允许检查任何POD结构成员的公共初始序列;见9.2。联合的大小足以容纳其最大的数据成员。每个数据成员都被分配为好像它是结构的唯一成员。


这意味着每个成员共享相同的存储区域。这里是活跃在最一个成员,但你不能找出哪一个。您将不得不将有关当前活动成员的信息自己存储在其他地方。除了联合以外,还存储这样的标志(例如,将具有整数作为类型标志的结构并将联合作为数据存储区)将为您提供所谓的“区分联合”:知道哪种类型的联合它目前是“活跃的”。


词法分析器的一种常见用法是,您可以具有不同的令牌,但是根据令牌的不同,您可以存储不同的信息(放入line每个结构以显示常见的初始序列是什么):


struct tokeni {

    int token; /* type tag */

    union {

        struct { int line; } noVal;

        struct { int line; int val; } intVal;

        struct { int line; struct string val; } stringVal;

    } data;

};

该标准允许您访问line每个成员,因为这是每个成员的共同初始序列。


存在一些编译器扩展,这些扩展允许访问所有成员,而不管当前存储了其值的成员。这样可以有效地重新解释每个成员之间具有不同类型的存储位。例如,以下内容可用于将float变量分解为2个无符号短裤:


union float_cast { unsigned short s[2]; float f; };

在编写低级代码时,这可能非常方便。如果编译器不支持该扩展名,但是您仍然这样做,则编写未定义结果的代码。因此,如果使用该技巧,请确定您的编译器对此有支持。


查看完整回答
反对 回复 2019-11-18
?
撒科打诨

TA贡献1934条经验 获得超2个赞

一个a union总是占用最大成员的空间。现在使用什么都没关系。


union {

  short x;

  int y;

  long long z;

}

上面的一个实例union将始终至少需要a long long进行存储。


附注:由于注意到斯特凡诺,实际空间的任何类型(union,struct,class)将采取不依赖于其他问题,如编译器对齐。我并不是为了简单起见,因为我只想告诉我工会考虑了最大的项目。重要的是要知道实际大小确实取决于alignment。


查看完整回答
反对 回复 2019-11-18
  • 3 回答
  • 0 关注
  • 561 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信