【发布时间】:2010-11-05 21:22:23
【问题描述】:
在 C 中测试和设置整数中的各个位的经典问题可能是最常见的中级编程技能之一。您可以使用简单的位掩码进行设置和测试,例如
unsigned int mask = 1<<11;
if (value & mask) {....} // Test for the bit
value |= mask; // set the bit
value &= ~mask; // clear the bit
interesting blog post 认为这容易出错、难以维护且实践不佳。 C 语言本身提供类型安全且可移植的位级访问:
typedef unsigned int boolean_t;
#define FALSE 0
#define TRUE !FALSE
typedef union {
struct {
boolean_t user:1;
boolean_t zero:1;
boolean_t force:1;
int :28; /* unused */
boolean_t compat:1; /* bit 31 */
};
int raw;
} flags_t;
int
create_object(flags_t flags)
{
boolean_t is_compat = flags.compat;
if (is_compat)
flags.force = FALSE;
if (flags.force) {
[...]
}
[...]
}
但这让我畏缩。
我和我的同事对此的有趣争论仍未解决。这两种风格都有效,我认为经典的位掩码方法简单、安全、清晰。我的同事同意它很常见且简单,但位域联合方法值得多花几行代码以使其可移植且更安全。
双方还有什么争论吗?特别是是否存在一些可能的失败,也许是字节顺序,位掩码方法可能会丢失,但结构方法在哪里是安全的?
【问题讨论】:
-
我认为你畏缩是对的。
-
flags.compat和flags.force是如何工作的?他们不应该是flags.{structure_name}.compat和flags.{structure_name}.force吗? -
@Lazer 可以直接在 gcc GNU 扩展中引用未命名的 struct/union 的成员,现在是 C11 标准。
-
以这种方式使用位域是高度不可移植的。请参阅en.cppreference.com/w/c/language/bit_field 注释部分:未指定位字段的对齐和排序。
标签: c bit-manipulation