什么是在基于臂的拱上声明标志的更好方法?

时间:2012-12-03 19:04:03

标签: c linux linux-kernel arm

基于手臂的弓有什么好处?

struct my_struct{
    struct device   *dev;
    unsigned char   a:1,
            b:1,
            v:1,
            d:1;
};

或者定义一个char并使用位操作:

struct my_struct{
    struct device   *dev;
    unsigned char abcd;
};

3 个答案:

答案 0 :(得分:4)

我不认为处理器的架构对这个问题很重要。在许多方面,这纯粹是一种风格问题。

根据我的经验,大多数人倾向于使用无符号整数和逐位运算:

#define MASK_B 0x20;
unsigned char field;
int b_is_set = field & MASK_B;

在主流代码中,位域似乎从未真正起飞。

话虽如此,我会用你觉得更自然的一切。

答案 1 :(得分:1)

要做的第一件事就是考虑对齐,详细了解这些问题unaligned-memory-accessmem_alignment

可伸缩性或开销是第二个非常重要的事情。如果这个结构将被多次分配,例如缓存条目或者使用文件系统内部结构,那么你需要保持紧凑。

可读性也非常重要,但由于这是一个操作系统内核,我们所说的是你需要提供的性能和维护,这是你应该有意识地做出的权衡。

答案 2 :(得分:1)

位字段打包顺序是实现定义的。这意味着如果你宣布

struct my_struct {
    struct device  *dev;
    unsigned char   a:1,
                    b:1,
                    c:1,
                    d:1;
};

完全取决于编译器决定abcd实际驻留在哪里。(GCC和其他一些编译器确定{{ 1}}或__BIG_ENDIAN_BITFIELD取决于它们如何打包位域。)

另一方面,如果你定义

__LITTLE_ENDIAN_BITFIELD

您知道struct my_struct { struct device *dev; unsigned char abcd; }; #define MASK_A (1U << 0U) #define MASK_B (1U << 1U) #define MASK_C (1U << 2U) #define MASK_D (1U << 3U) static inline unsigned char get(const struct my_struct *const m, const unsigned char mask) { return m->abcd & mask; } static inline unsigned char set(struct my_struct *const m, const unsigned char mask, const unsigned char value) { m->abcd = (m->abcd & mask) | (mask & value); return m->abcd & mask; } static inline unsigned char flip(struct my_struct *const m, const unsigned char mask) { m->abcd ^= mask; return m->abcd & mask; } 映射到指针后面字节中的最低有效位,a映射到第二位,b第三位,c第四位。< / p>

如果你的C编译器支持d,那么这些函数和宏一样快,但没有问题宏有wrt。副作用。

这也允许您将位字段作为一个组进行操作。例如,要在结构static inline中设置b,您需要使用t。要设置set(&t, MASK_B, MASK_B)但要清除b,您需要使用a。要测试是否设置了set(&t, MASK_A | MASK_B, MASK_B),请使用a。要测试是否设置了get(&t, MASK_A)a,请使用b。要检查是否设置了get(&t, MASK_A | MASK_B)a,请使用b。所有三个函数都返回结果位掩码,应用掩码,即所有其他位为零。

就个人而言,我更喜欢后一种方法,主要是因为我觉得它更明确(我完全掌控),更多功能(允许我不仅可以单独操作它们,而且可以分组操作),并且更节省空间(因为编译器倾向于添加填充,除非你明确告诉他们不要通过例如命令行开关)。根据您使用标志的方式,我建议您通过宏或静态内联函数访问它们。

那就是说,如果结构是应用程序的内部结构,从不存储在大容量存储器中或传输,我不会对这两种方法都有任何实际的反对意见。