一次测试C中的所有位文件

时间:2016-11-01 14:23:07

标签: c

我们说我的C结构定义为

struct data {
    /* some memebers */

    int flag_a:1;
    int flag_b:1;
    int flag_c:1;

    /* some other members */
}

有没有办法利用在内存中表示为单个int的位域,并将条件s.flag_a | s.flag_b | s.flag_c写为更简单的表达式,例如s.flags

或者像GCC这样的智能编译器能够实际推断它吗?

编辑:为了让自己绝对清楚:我正在寻找一种可移植的方式来测试所有正在设置的标志,而不是分别明确地测试每个标志。

2 个答案:

答案 0 :(得分:7)

这不可能以任何确定的方式进行移植。问题是C标准不能保证这些位的任何内容:你不能知道哪个位是LSB,也不知道是否有填充。最重要的是,endianess也是一个问题。 (理论上,不同的签名格式。)See this for details

理论上,你可以在这个位字段和一个: 3位之间创建一个联合,但这种实践的结果将不可预测,也不能很好地定义。

最好的解决方案是摆脱位字段并用确定性的100%便携式解决方案替换它:

typedef struct
{
  uint8_t flags;
} data_t

#define FLAG_A 0x01u
#define FLAG_B 0x02u
#define FLAG_C 0x04u
#define FLAG_ALL (FLAG_A | FLAG_B | FLAG_C)

data_t data = { .flags = FLAG_A | FLAG_B | FLAG_C};

if(data.flags & FLAG_ALL)
  ...

答案 1 :(得分:2)

比特字段使用完全不可移植。您无法确定 每个字段在底层结构中的位置。 Per 6.7.2.1结构和联合说明符the C Standard的第11段:

  

实现可以分配任何可寻址的存储单元   足以容纳一个位域。如果剩余足够的空间,那就是一个位域   紧接着结构中的另一个位字段应该被打包   进入同一单元的相邻位。如果剩余空间不足,   是否将不适合的位域放入下一个单元或   重叠相邻单元是实现定义的。 的顺序   单位内的位域分配(高位到低位或   低阶到高阶)是实现定义的。对齐   可寻址存储单元未指定。