Q:里面的bitset是怎么来的?

Q: How bitset are inside?

问题很简单(问),std::bitset<32>uint32_t对于内存来说是一回事吗?或者它更像是 std::array<bool, 32> ?

我通常会这样做:

uint32_t  index : 20;
uint32_t  magic : 12;

所以它和这段代码一样?

std::bitset<20>  index;
std::bitset<12>  magic;

一个位域需要一个结构体

struct {
    uint32_t index : 20;
    uint32_t magic : 12;
}

所以和

不一样
std::bitset<20>  index;
std::bitset<12>  magic;

"Multiple adjacent bit fields are usually packed together (although this behavior is implementation-defined): ".

你有两个 std::bitset 所以他们不能共享相同的内存,所以这不是一回事。

uint32_t  index : 20;
uint32_t  magic : 12;

So it's the same as this code ?

std::bitset<20>  index;
std::bitset<12>  magic;

绝对不是,了解其中的区别非常重要。

首先,std::bitset<>的内部表示是向下实现。

除此之外,我们应该检查上面两个代码片段之间的区别。

在 c++ 中,位域 不是离散对象。这在多线程代码中具有重要意义。

这是因为 c++11 和更高版本保证从两个线程对两个离散对象的不受保护的访问是安全的,但是另外两个线程对同一个非常量对象的访问是数据竞争,除非受到保护互斥。

在上面的 bitset 代码中,正确的说法是:

线程 1:index = 10;

线程 2:auto x = magic;

因为它们是离散对象,因此保证在从不同线程访问时不会导致数据竞争。

bitfield 代码中,这不安全。索引的更新将是一场与魔法阅读的竞赛,这是未定义的行为。