结构中的位是否保证是连续的?

are bits in structs guaranteed to be contiguous?

我玩过 https://gcc.godbolt.org/,这段代码似乎总是 return 1.

但是我想知道标准是否保证这一点。

#include <cstdint>

struct S{
   uint8_t a : 6;
   uint8_t b : 2;
};

int main(){
    return sizeof(S);
}

我的真实例子如下:

struct Pair{
    uint64_t    created;    // 8 bytes
    uint32_t    expires;    // 4 bytes
    uint16_t    keylen;     // 2 bytes, 4 bits are used for vallen. 2 bits are reserved for future versions. 10 bytes for keylen.
    uint16_t    vallen;     // 2  bytes
};

目前我在做一些位掩码和移位。

我可以这样做吗?它会一直工作吗(任何“普通”编译器)?

keylen 在 Big Endian 上的表现如何?使用移位我总是使用前 4 位。

struct Pair{
    uint64_t    created;
    uint32_t    expires;
    uint8_t     vallen2 : 4;
    uint8_t     future  : 2;
    uint16_t    keylen  : 10;
    uint16_t    vallen; 
};

大多数编译器会为您提供打包在一起的位字段,尽管行为是实现定义的。

一种检查方法是添加 static_assert 来比较有无位域的结构定义的大小。这样,一旦实现没有按照您的预期进行,您将得到一个不错的编译时错误。

#include <cstdint>

struct Pair_size_check{
    uint64_t    created;    // 8 bytes
    uint32_t    expires;    // 4 bytes
    uint16_t    keylen;     // 2 bytes, 4 bits are used for vallen. 2 bits are reserved for future versions. 10 bytes for keylen.
    uint16_t    vallen;     // 2  bytes
};

struct Pair{
    uint64_t    created;
    uint32_t    expires;
    uint8_t     vallen2 : 4;
    uint8_t     future  : 2;
    uint16_t    keylen  : 10;
    uint16_t    vallen; 
};

static_assert(sizeof(Pair) == sizeof(Pair_size_check));