联合与比特屏蔽和比特移位

时间:2013-02-07 06:44:53

标签: c++ c unions bit-shift bitmask

在存储一些字节等信息并且能够一次或逐个访问它们时使用unions有什么缺点。

示例:颜色可以用RGBA表示。因此颜色类型可以定义为,

typedef unsigned int RGBAColor;

然后我们可以使用“移位和屏蔽”位来“检索或设置”RGBAColor对象的红色,绿色,蓝色,alpha值(就像在Direct3D函数中使用像{{{ 1}})。

但是,如果我使用了一个联盟,

D3DCOLOR_ARGB()

然后我不需要总是进行移位(union RGBAColor { unsigned int Color; struct RGBAColorComponents { unsigned char Red; unsigned char Green; unsigned char Blue; unsigned char Alpha; } Component; }; )或掩蔽(<<)来读取或写入颜色分量。但这有问题吗? (我怀疑这有一些问题,因为我没有看到有人使用这种方法。)

Endianness可以成为一个问题吗?如果我们总是使用&来访问颜色组件并使用Component来访问整个事物(用于复制,分配等等......),那么字节顺序应该不是问题,对吧?

- 编辑 - 我找到了一个老帖子,这是同样的问题。所以我想这个问题有点重新发布:P对不起。这是链接:Is it a good practice to use unions in C++?

根据答案,似乎在C ++中使用给定示例的联合是可以的。因为那里没有数据类型的变化,它只有两种方式来访问相同的数据。如果我错了,请纠正我。谢谢。 :)

2 个答案:

答案 0 :(得分:1)

这种联合使用在C ++中是非法的,其中联合包含重叠但互斥的对象。你不能写一个工会的一个成员,然后读出另一个成员。

在C中这是合法的,这是推荐的打字方式。

这涉及(严格)别名的问题,这是编译器在尝试确定具有不同类型的两个对象是否不同时所面临的困难。语言标准不一致,因为专家们仍在确定可以安全地提供哪些保证而不牺牲性能。就个人而言,我避免所有这一切。 int实际上会用于什么?翻译的安全方法是复制字节,如memcpy

还有字节序问题,但这是否重要取决于您对int的要求。

答案 1 :(得分:0)

我相信使用union 解决与字节序相关的任何问题,因为很可能RGBA顺序是按网络顺序定义的。此外,每个组件都是uint8_t或类似的事实,可以帮助一些编译器使用符号/零扩展加载,将低8位直接存储到非符号字节指针,甚至能够并行化一些字节操作(例如,arm有一些打包4x8位指令)。