我刚刚发现了bitflags的乐趣.我有几个关于在C语言中使用bitflags的"最佳实践"的问题.我从网上找到的各种例子中学到了一些东西,但仍然有问题.
为了节省空间,我在struct(A->flag
)中使用单个32位整数字段来表示几组不同的布尔属性.总共有20个不同的位#define
.其中一些是真正的存在/不存在标志(STORAGE-INTERNAL与STORAGE-EXTERNAL).其他人有两个以上的值(例如互斥的格式集:FORMAT-A,FORMAT-B,FORMAT-C).我已经定义了用于设置特定位的宏(同时关闭互斥位).如果在标志中设置了特定的位组合,我还定义了用于测试的宏.
但是,上述方法中丢失的是标记的特定分组,最好由枚举捕获.对于编写函数,我想使用枚举(例如,STORAGE-TYPE和FORMAT-TYPE),以便函数定义看起来不错.我希望仅使用枚举来传递参数,使用#defined宏来设置和测试标志.
(a)如何A->flag
以便携方式(跨32位/ 64位平台)将flag()定义为32位整数?
(b)我是否应该担心如何存储A->flag
与#define
d常量与枚举相比的潜在大小差异?
(c)我是否使事情变得不必要地复杂化,这意味着我应该坚持使用#define
d常量来传递参数作为普通的int
s?在这一切中我还应该担心什么?
我为这个表达不清的问题道歉.它反映了我对潜在问题的无知.
有一个C99标题旨在解决这个确切的问题(a)但由于某种原因,微软没有实现它.幸运的是,你可以
在这里获得Microsoft Windows.每个其他平台都已经拥有它.32位int类型是uint32_t
和int32_t
.它们还有8,16和64位的味道.
所以,这照顾(a).
(b)和(c)是同一个问题.每当我们开发某些东西时,我们都会做出假设 您假设C将可用.你认为
可以在某处找到.您可以始终假设int
至少为16位,现在> = 32位假设是相当合理的.
通常,您应该尝试编写不依赖于布局的符合性程序,但是它们会对字长做出假设.您应该担心算法级别的性能,也就是说,我写的是二次,多项式,指数的东西吗?
在(a)您发现性能滞后,以及(b)您已对程序进行了分析之前,您不必担心操作级别的性能.你需要完成工作,而不必担心个别操作.:-)
哦,我应该补充一点,当您首先在C语言中编写程序时,尤其不需要担心低级操作性能.C是接近金属的快速尽可能快的语言.我们经常在php,python,ruby或者lisp中写东西,因为我们想要一个强大的语言,而且CPU现在如此之快,以至于我们可以使用整个解释器,不用担心一个不完美的位旋转字的选择长度的操作.:-)
你可以使用位字段让编译器做一点点.例如:
struct PropertySet { unsigned internal_storage : 1; unsigned format : 4; }; int main(void) { struct PropertySet x; struct PropertySet y[10]; /* array of structures containing bit-fields */ if (x.internal_storage) x.format |= 2; if (y[2].internal_storage) y[2].format |= 2; return 0; }
编辑添加结构数组