使用 1 个字节而不是 1 位的位域

Bitfield using 1 byte instead of 1 bit

我正在开发一个网络应用程序,我将接收 2 个字节并且某些位具有特定意义。我正在尝试将该数据包实现为一个结构。目的是对对象地址进行二进制复制,并且可以访问数据包的字段。这是一个代表我的问题的简单示例。当我们尝试检查位域和结构的大小时,它们并没有按预期出现。

#include <bitset>
#include<iostream>
struct a
    {
        std::bitset<8> b;
        uint8_t c;

    };
int main()
{
    std::cout<<sizeof(a);
}

输出:8

预期输出:2

这是 Bitset 实现的特定内容吗?

一般来说,每个元素只占用一位(在大多数系统上,它比最小的元素类型:char 小八倍)。 (参考 - cplusplus.com/reference/bitset/bitset/

在 Microsoft Visual Studio 2019 16.10.2

上编译

微软Visual Studio'STL的源代码最近开源了,大家可以查看bitsethere的实现,可以确认数据结构是array, 草图:

template <size_t _Bits>
class bitset { // store fixed-length sequence of Boolean elements
public:
    using _Ty = conditional_t<_Bits <= sizeof(unsigned long) * CHAR_BIT, unsigned long, unsigned long long>;
    static constexpr ptrdiff_t _Bitsperword = CHAR_BIT * sizeof(_Ty);
    static constexpr ptrdiff_t _Words       = _Bits == 0 ? 0 : (_Bits - 1) / _Bitsperword; // NB: number of words - 1
    _Ty _Array[_Words + 1];
};

所以对于std::bitset<8>,底层数组是unsigned long _Array[1]。然后我们得到大小:4。对于sizeof struct a的结果我们得到8,这是由于bc周围对齐造成的,请参考这个关于对齐。

由于是处理网络应用,这里不适合使用bitset。要解码网络协议,最好使用位域。 seastar的tcp decoder里面有很好的例子,你可以拿来举例