可变大小的位域混叠与(Variable-sized bitfields with aliasing)

2019-10-17 17:48发布

我有一些结构containig位域,其尺寸可变化。 例:

struct BitfieldSmallBase {
    uint8_t a:2;
    uint8_t b:3;
    ....
}

struct BitfieldLargeBase {
    uint8_t a:4;
    uint8_t b:5;
    ....
}

工会同时访问所有位:

template<typename T>
union Bitfield 
{
    T bits;
    uint8_t all;    // <-------------  Here is the problem

    bool operator & (Bitfield<T> x) const {
        return !!(all & x.all);
    }
    Bitfield<T> operator + (Bitfield<T> x) const {
        Bitfield<T> temp;
        temp.all = all + x.all;   //works, because I can assume no overflow will happen
        return temp;
    }
    ....
}

typedef Bitfield<BitfieldSmallBase> BitfieldSmall;
typedef Bitfield<BitfieldLargeBase> BitfieldLarge;

问题是:对于一些位域的基类,一个uint8_t是不够的。 BitfieldSmall不适合一个uint8_t,但BitfieldLarge没有。 这些数据需要(这将SSE指令后处理)被包装尽可能紧,所以总是使用uint16_t是毫无疑问的。 是否有与整型,其大小是一样的位域申报“所有”字段的方法吗? 或者另一种方式来访问位作为一个整体?

当然,我可以放弃使用模板,并明确申报各种位域的,但我想,以避免重复代码(有运营商UND成员函数相当的列表)。

Answer 1:

你可以使整体式模板参数为好。

template<typename T, typename U>
union Bitfield 
{
    T bits;
    U all;
}

typedef Bitfield<BitfieldSmallBase, uint8_t>  BitfieldSmall;
typedef Bitfield<BitfieldLargeBase, uint16_t> BitfieldLarge;


Answer 2:

我学到了艰辛的道路,虽然在您使用瓦尔位宽为让编译器做你的遮蔽,并为您的控制换档的便捷的方式,你不能对在该成员的顺序和填充假设结构。 它依赖于编译器和编译器确实改变顺序,这样依赖于项目的其他代码。

如果你要正确对待一个字节为离散领域,你真的必须这样做,艰难地。



Answer 3:

您可以使用模板元编程来定义,从BitfieldSmallBase,BitfieldLargeBase等映射到另一种类型的模板函数 - 默认uint8_t和BitfieldLargeBase到uint16_t为模板专业化,然后使用这样的:

union Bitfield 
{
    T bits;
    typename F<T>::holder_type all;
};


Answer 4:

你可能要考虑的std :: bitset的或提振::来,dynamic_bitset而不是滚动您自己。 在任何情况下, 避开std::vector<bool>



Answer 5:

让你需要的模板参数的一部分的字节数:

template <typename T, int S=1>
struct BitField 
{
   union
   {
      T bits;
      unsigned char bytes[S];
   };
};

typedef Bitfield<BitfieldSmallBase, 1>  BitfieldSmall;
typedef Bitfield<BitfieldLargeBase, 2> BitfieldLarge;


Answer 6:

这个怎么样?

#include <limits.h>

template <class T>
union BitField
{
    T bits;
    unsigned all : sizeof(T) * CHAR_BIT;
};


文章来源: Variable-sized bitfields with aliasing