C++ C/C++;位字段与按位运算符相比,可以选择更快、更好、更便于携带的位?

C++ C/C++;位字段与按位运算符相比,可以选择更快、更好、更便于携带的位?,c++,c,bit-manipulation,bit-fields,C++,C,Bit Manipulation,Bit Fields,我需要以这种方式将一些位打包到一个字节中: struct { char bit0: 1; char bit1: 1; } a; if( a.bit1 ) /* etc */ 或: 从源代码的清晰性来看,我很明显,位字段更整洁。但哪种选择更快?我知道速度差不会太大,如果有的话,但我可以使用其中任何一种,如果速度更快,就更好。 另一方面,我读到比特域不能保证在不同平台上以相同的顺序排列比特,我希望我的代码是可移植的 注意:如果你打算回答“个人资料”,我会的,但因为我很

我需要以这种方式将一些位打包到一个字节中:

struct  
{  
  char bit0: 1;  
  char bit1: 1;  
} a;  

if( a.bit1 ) /* etc */
或:

从源代码的清晰性来看,我很明显,位字段更整洁。但哪种选择更快?我知道速度差不会太大,如果有的话,但我可以使用其中任何一种,如果速度更快,就更好。
另一方面,我读到比特域不能保证在不同平台上以相同的顺序排列比特,我希望我的代码是可移植的

注意:如果你打算回答“个人资料”,我会的,但因为我很懒,如果有人已经有了答案,那就更好了。

代码可能是错误的,如果你愿意,你可以纠正我,但是记住这个问题的要点,请尝试回答它

如果您想要可移植性,请避免使用位字段。而且,若您对特定代码的性能感兴趣,那个么除了编写自己的测试之外,别无选择。请记住,位字段将在后台使用处理器的位指令。

我认为C程序员倾向于使用位掩码和逻辑运算来推断每个位的值的第二种选择。与其让代码中充斥着十六进制值,不如设置枚举,或者通常在涉及更复杂的操作时,设置宏来获取/设置特定的位。我在小道消息中听说,结构实现的位域速度较慢。

第一个是显式的,无论第二个表达式的速度如何,都容易出错,因为对结构的任何更改都可能使第二个表达式出错


因此,请使用第一个。

如果使用得当,位字段会使代码更加清晰。我只会将位字段用作节省空间的设备。我看到它们在编译器中使用的一个常见位置是:类型或符号信息通常由一组真/假标志组成。位字段在这里是理想的,因为一个典型的程序在编译时会创建数千个这样的节点

我不会使用位字段来完成一项常见的嵌入式编程工作:读取和写入设备寄存器。我更喜欢在这里使用移位和掩码,因为您可以得到文档中告诉您需要的位,并且不必担心不同编译器实现位字段的差异


至于速度,一个好的编译器将为位字段提供与掩蔽相同的代码。

C位字段从发明之日起就死气沉沉,原因不明。人们不喜欢它们,而是使用位运算符。您必须期望其他开发人员不理解C位域代码


关于哪个更快:无关紧要。任何优化编译器(实际上意味着所有)都将使代码以任何符号执行相同的操作。对于C程序员来说,编译器只是搜索关键字并将其替换到汇编中,这是一个常见的误解。现代编译器使用源代码作为实现目标的蓝图,然后发出看起来非常不同但达到预期结果的代码。

为了最大的可移植性,我宁愿使用第二个示例。正如Neil Butterworth所指出的,使用位字段仅适用于本机处理器。好的,想想看,如果英特尔的x86明天停业,代码会被卡住,这意味着必须为另一个处理器重新实现位字段,比如RISC芯片

您必须从更大的角度来看,并询问OpenBSD是如何使用一个代码库将其BSD系统移植到许多平台的?好吧,我承认这有点过头了,有争议而且主观,但现实地说,如果你想把代码移植到另一个平台,那么使用你在问题中使用的第二个例子就是这样做的

不仅如此,不同平台的编译器也有自己的填充方式,为编译器所在的处理器对齐位字段。而且,处理器的持久性呢

永远不要把比特域当作魔弹。如果您想要处理器的速度,并且将固定在处理器上,即不打算移植,那么可以随意使用位字段你不能两者兼得

不要在“非便携位字段”中读取太多内容。位字段有两个方面是实现定义的:有符号性和布局,还有一个方面是未指定的:它们所在的分配单元的对齐。如果您不需要任何其他的打包效果,那么使用它们就像函数调用一样具有可移植性(如果您在需要时明确指定
带符号的
关键字),函数调用也具有未指定的属性

关于性能,profile是您能得到的最佳答案。在一个完美的世界里,这两部作品之间没有什么区别。在实践中,可能会有一些原因,但我可以从一个方向和另一个方向想出尽可能多的原因。而且它对上下文非常敏感(例如,无符号和有符号之间在逻辑上没有意义的区别),所以在上下文中度量


总而言之,在您真正有选择的情况下(即,如果精确的布局很重要的话),这种差异主要是风格上的差异。在这种情况下,它是一种优化(在大小上,而不是在速度上),因此我倾向于首先编写没有它的代码,然后在需要时添加它。因此,位字段是显而易见的选择(要进行的修改是实现结果的最小修改,并且包含在唯一的定义位置,而不是扩展到所有使用位置)

你可能对我感兴趣。至少还有一个我记得评论过的非常类似的问题(似乎不是这个问题)!谢谢大家,哇。我们在这里上了宝贵的一课。为什么除了位字段排序之外,位字段是不可移植的?此外,一些处理器也支持位字段插入/提取。例如,68020就做到了
if( a & 0x2 ) /* etc */