【发布时间】:2010-06-21 17:47:33
【问题描述】:
位域可以在联合中使用吗?
【问题讨论】:
-
做两件恶事时,是相加还是相乘? ;-)
-
+1 到 Amardeep。不要也不要 divya。
-
较近的位域和联合一定是邪恶的。我在联合中使用结构来解析嵌入式软件中的字节输入/输出。它的舒适性超过了它的缺点。
标签: c bit-fields unions
位域可以在联合中使用吗?
【问题讨论】:
标签: c bit-fields unions
是的,他们可以。为什么不?联合中的位域的行为方式与它们在其他任何地方的行为方式相同。联合中的位域(或带有位域的联合)没有什么特别之处。
【讨论】:
是的,这是可能的,但我建议不要这样做。位域的长度和打包是不可移植的。联合体的规模将难以预测(参见here)。当您使用联合或位域时,您会在代码中引入一定程度的复杂性。虽然这种复杂性在您的代码中可能是可以接受的,但将两者结合起来可能会导致无法接受的复杂性。如果您使用联合、结构和位域,则会遇到内存对齐问题。
如果这是只需要在一台机器上构建和运行的一次性代码,那么它可能没问题。但是,如果您将其签入到版本控制中,它将永远存在,我建议您不要这样做。
如果您举例说明为什么要这样做,我或其他人可以提出更好的替代方案。
编辑:根据 cmets 进行澄清并征求反馈意见。
【讨论】:
如果您考虑一下 union 的工作原理,您会有答案,当然是肯定的(为什么不)?正如我们所期望的,联合大到足以容纳最大的基准,因此自然而然地就更小了。位域被打包到“容器”中,编译器必须能够评估它们的最终实际大小。下面展示了一些有趣的事实(当然是联合的错误用法,但不是针对位域的存在!)
#include <stdio.h>
union test {
int a:5;
int b:12;
float c;
double d;
int x;
};
int main()
{
union test x;
printf("%d\n", sizeof(x));
x.a = 31;
printf("%d\n", x.a);
printf("%d\n", x.b);
x.c = 1.23;
printf("%d\n", x.a);
printf("%f\n", x.c);
x.x = 31;
printf("%d\n", x.x);
printf("%d\n", x.a);
printf("%d\n", x.b);
}
【讨论】:
只有写入一个联合元素并从另一个联合元素读取,这才是不安全的。如果您的实现细节确保不会发生这种情况,那么包含 bitfied(可能还有其他成员)的联合具有定义明确的安全行为。
【讨论】:
reinterpret_cast 类似。技术勘误 3 清楚地说明了这一点。