【问题标题】:are bits in structs guaranteed to be contiguous?结构中的位是否保证是连续的?
【发布时间】:2020-09-22 07:20:51
【问题描述】:

我玩过https://gcc.godbolt.org/,这段代码似乎总是返回 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; 
};

【问题讨论】:

  • 这能回答你的问题吗? Force C++ structure to pack tightly
  • struct __attribute__ ((packed)) 包对齐。我要的是“位域”
  • 引用cppreferenceMultiple adjacent bit fields are usually packed together (although this behavior is implementation-defined)。您可以添加static_assert 来检查您在此处给出的Pair 的两个版本是否为您提供了相同的sizeof
  • 如果您想控制位的打包方式,我建议您使用位掩码,因为 1B 是最小可寻址值。这样,您不必关心编译器如何优化内存以及它如何重新对齐位。我还补充说,这通常不是您应该关心的事情,除非在某些边缘情况下
  • @Nick 抱歉,没看到

标签: c++ struct bit


【解决方案1】:

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

一种检查方法是添加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));

【讨论】:

  • 对字节序有任何想法吗?
  • 字节序不影响位移。如果您需要序列化或 memcpy 数据,这只是一个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 2010-10-25
  • 1970-01-01
  • 2012-04-03
  • 2012-01-22
  • 2014-01-21
相关资源
最近更新 更多