位压缩结构体内的数组

4

我希望在一个位压缩的结构体中有一个数组。我静态地知道数组的大小(32),我希望数组中的每个元素都是一个单独的位。例如,我希望能够这样说:

struct example_s {
  // ...
  unsigned int flags[32] : 32;
} __attribute__((__packed__));

我尝试了几个方法,但gcc不会让步。如果能够这样做,那将很好,因为我可以编写干净的代码来迭代打包数组中的元素。有什么想法吗?


这是针对内存映射I/O吗? - nmichaels
不是的。这是为了存储在堆栈上并从中访问的一些运行时元数据。 - mhahnenb
2个回答

7

如果你只是将它放入(32位)整数中,那么你可以通过for循环清晰地迭代这些位,就像这样:

for (bit = 0; bit < 32; bit++)
    flagValue = ((flags & (1<<bit)) != 0;

这段代码的难度不比数组索引语法高。

如果您希望隐藏位操作以使代码更易读,甚至可以使用函数或宏来访问位 - 例如,GetFlag(bit)


是的,宏看起来是前进的道路。哦,好吧! - mhahnenb

1

位域成员元素没有地址,因此即使您可以声明它们的数组,也无法使用它(在C中,所有数组访问都是指针算术和解引用)。不过,使用较大类型的位来编写自己的位数组很容易;Jason已经解释了基础知识。通常情况下,除非您有非常好的理由,否则应避免使用位域。它们通常会带来更多麻烦。


你可以用同样的方式来描述结构体成员 - 编译器通常会从结构体的基地址生成偏移量。对于位压缩结构体,它需要进行一些额外的操作才能获取和设置值。因此,我认为编译器在处理数组时也可以进行类似的幕后魔法。而且我有使用位域的充分理由 :-) - mhahnenb
如果struct foo有一个成员char bar[10],那么foo.bar是一个表达式,其评估为类型char *,并且foo.bar[2]被评估为*(foo.bar+2),从而使其正常工作。数组语法a[b]只是*(a+b)的语法糖(和方便的无需括号的分组)。 - R.. GitHub STOP HELPING ICE
如果你有一个“好的理由”使用位域,我认为你没有理解Jason的答案。尝试查找位数组实现 - 无论是在谷歌上还是在SO的过去问题中 - 我认为你会找到令人满意的答案。 - R.. GitHub STOP HELPING ICE
抱歉,我一开始可能误解了您的意思。您是说如果foo被位压缩,那么foo中的数组bar可能无法被寻址吗? - mhahnenb
@mhahnenb:问题在于,C语言中数组解引用的显式语义是将数组转换为指向其第一个元素的指针,添加偏移量,然后对结果进行解引用。这就是语言中[]运算符的定义方式。而.运算符并非如此,这就是为什么不会出现相同的问题的原因。 - caf
如果C标准规定在数组上的[]操作与在结果指针上分解后跟随的[]操作不同(这将解决许多其他问题),那么位域数组将不会造成语义问题。 - supercat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接