简体   繁体   English

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

[英]union vs bit masking and bit shifting

What are the disadvantages of using unions when storing some information like a series of bytes and being able to access them at once or one by one. 在存储一些信息(如一系列字节)并能够一次或逐个访问它们时使用unions有什么缺点。

Example : A Color can be represented in RGBA. 示例:颜色可以用RGBA表示。 So a color type may be defined as, 所以颜色类型可以定义为,

typedef unsigned int RGBAColor;

Then we can use "shifting and masking" of bits to "retrieve or set" the red, green, blue, alpha values of a RGBAColor object ( just like it is done in Direct3D functions with the macro functions such as D3DCOLOR_ARGB() ). 然后我们可以使用位的“移位和屏蔽”来“检索或设置”RGBAColor对象的红色,绿色,蓝色,alpha值(就像在具有诸如D3DCOLOR_ARGB()类的宏函数的Direct3D函数中完成一样)。

But what if I used a union, 但是,如果我使用了一个联盟,

union RGBAColor
{
unsigned int Color;
struct RGBAColorComponents
{
    unsigned char Red;
    unsigned char Green;
    unsigned char Blue;
    unsigned char Alpha;
} Component;
};

Then I will not be needing to always do the shifting ( << ) or masking ( & ) for reading or writing the color components. 然后我不需要总是进行移位( << )或屏蔽( & )来读取或写入颜色分量。 But is there problem with this? 但这有问题吗? ( I suspect that this has some problem because I haven't seen anyone using such a method. ) (我怀疑这有一些问题,因为我没有看到有人使用这种方法。)

Can Endianness Be a broblem? Can Endianness可以成为一个问题吗? If we always use Component for accessing color components and use Color for accessing the whole thing ( for copying, assigning, etc.. as a whole ) the endianness should not be a problem, right? 如果我们总是使用Component来访问颜色组件并使用Color来访问整个事物(用于复制,分配等等),那么字节顺序应该不是问题,对吧?

-- EDIT -- I found an old post which is the same problem. - 编辑 - 我发现一个旧帖子也是同样的问题。 So i guess this question is kinda repost :P sorry for that. 所以我想这个问题有点重新发布:P对不起。 here is the link : Is it a good practice to use unions in C++? 这里是链接: 在C ++中使用联合是一个好习惯吗?

According to the answers it seems that the use of unions for the given example is OK in C++. 根据答案,似乎在C ++中使用给定示例的联合是可以的。 Because there is no change of data type in there, its just two ways to access the same data. 因为那里没有数据类型的变化,它只有两种方式来访问相同的数据。 Please correct me if i am wrong. 如果我错了,请纠正我。 Thanks. 谢谢。 :) :)

This usage of unions is illegal in C++, where a union comprises overlapping, but mutually exclusive objects. 在C ++中,这种联合使用是非法的,其中联合包含重叠但互斥的对象。 You are not allowed to write one member of a union, then read out another member. 你不能写一个工会的一个成员,然后读出另一个成员。

It is legal in C where this is a recommended way of type punning. 它在C中是合法的,这是推荐的打字方式。

This relates to the issue of (strict) aliasing, which is a difficulty faced by the compiler when trying to determine whether two objects with different types are distinct. 这涉及(严格)别名的问题,这是编译器在尝试确定具有不同类型的两个对象是否不同时所面临的困难。 The language standards disagree because the experts are still figuring out what guarantees can safely be provided without sacrificing performance. 语言标准不一致,因为专家们仍在确定可以安全地提供哪些保证而不牺牲性能。 Personally, I avoid all of this. 就个人而言,我避免所有这一切。 What would the int actually be used for? int实际上会用于什么? The safe way to translate is to copy the bytes, as by memcpy . 翻译的安全方法是复制字节,如memcpy

There is also the endianness issue, but whether that matters depends on what you want to do with the int . 还有endianness问题,但这是否重要取决于你想用int做什么。

I believe using the union solves any problems related to endianness, as most likely the RGBA order is defined in network order. 我相信使用union 可以解决与endianness相关的任何问题,因为很可能RGBA顺序是按网络顺序定义的。 Also the fact that each component will be uint8_t or such, can help some compilers to use sign/zero extended loads, storing the low 8 bits directly to a nonaligned byte pointer and being even able to parallelize some byte operations (eg arm has some packed 4x8 bit instructions). 此外,每个组件都是uint8_t或类似的事实,可以帮助一些编译器使用符号/零扩展加载,将低8位直接存储到非符号字节指针,甚至能够并行化一些字节操作(例如,arm有一些打包4x8位指令)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM