我有一个看起来像这样的结构:
#include <stdint.h>
struct bits {
uint8_t u_ : 1;
uint8_t k_ : 1;
uint8_t c_ : 1;
uint8_t x_ : 1;
uint8_t b_ : 1;
uint8_t ns_ : 1;
uint8_t ms_ : 1;
uint8_t as_ : 1;
uint8_t /*padding1*/ : 0;
uint8_t st_ : 3;
uint8_t su_ : 1;
uint8_t ig_ : 1;
uint8_t h_ : 1;
uint8_t in_ : 1;
uint8_t pad2_ : 1;
bits_t(uint8_t u, uint8_t k, uint8_t c, uint8_t x, uint8_t b,
uint8_t n, uint8_t m, uint8_t a, uint8_t s, uint8_t i,
bool h, bool in)
: u_ { u }
, k_ { k }
, c_ { c }
, x_ { x }
, b_ { b }
, ns_ { n }
, ms_ { m }
, as_ { a }
, st_ { 0 }
, su_ { s }
, ig_ { i }
, h_ { h }
, in_ { in }
, pad2_ { 0 } // carefully initialize all bits
{}
};
这些结构的
operator==
使用memcmp
,因此在构造函数中将所有位都设置为已知值非常重要。最近,我意识到
h_
和in_
在做相同的事情,除了相反的事情,即assert(h_ == !in_)
始终成立。我将要删除h_
,并且我想进行一些编译时检查,以警告我pad2_
需要从: 1
扩展到: 2
。这可能吗?我什么也没想(带或不带
sizeof(bits)
字段的h_
都是一样的)。 最佳答案
因此,无法查询位域的偏移量。因此,将很难在位域上创建任何约束。尽管以下预处理技巧可以帮助您实现所需的目标。
您本质上需要做的是使用宏创建结构字段。
带有2位字段的普通结构可以如下所示
#define STRUCT_NAME my_bitfield
#define FIELD_LIST \
FIELD(a,3) \
FIELD(b,5)
#define FIELD(x,y) int x:y;
struct STRUCT_NAME {
FIELD_LIST
};
到目前为止一切都很好。现在我们要做的是创建一个辅助struxt,它具有并行元素,但是每个元素都是n个字节
#undef FIELD
#define FIELD(x,y) char x[y];
struct aux_##STRUCT_NAME {
FIELD_LIST
};
凉。现在我们有了优势。我们可以使用此辅助结构的
sizeof
并检查它是否为8的倍数static_assert(sizeof(struct aux_##STRUCT_NAME) % 8 == 0);
现在,这将自动检查您的位域结构是否具有足够的位填充。
最后,要重新使用此代码,您可以在.h文件和您的主代码中添加实际的生成代码,只需重新定义
FIELD_LIST
和STRUCT_NAME
并包含标头即可。关于c++ - 如何检查位域是否覆盖所有位,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45820955/