有很多建议不要使用位字段,而是手动进行位运算(例如:When to use bit-fields in C?),因为位字段布局是实现定义的。
这是否是实际问题?例如,对于 x86-64 的 SysV ABI,定义了位字段应如何布局,因此我认为在该平台上使用位字段即使混合使用由不同编译器生成的目标代码也不应该有问题。
其他平台上的位字段是否也被标准化了?(我主要关心 Linux(SysV ABI)、MacOS 和 CygWin。)
有很多建议不要使用位字段,而是手动进行位运算(例如:When to use bit-fields in C?),因为位字段布局是实现定义的。
这是否是实际问题?例如,对于 x86-64 的 SysV ABI,定义了位字段应如何布局,因此我认为在该平台上使用位字段即使混合使用由不同编译器生成的目标代码也不应该有问题。
其他平台上的位字段是否也被标准化了?(我主要关心 Linux(SysV ABI)、MacOS 和 CygWin。)
struct
{
unsigned cnt: 3;
}three_bit_counter;
three_bit_counter.cnt++;
如果你编程使用uC - 是的
如果你想使用相同的代码并将数据“打包”到位域结构中 - 不可以。
这只是一些例子。编码时最好考虑许多选项,而不是受到“大师”意见的建议。
struct
{
unsigned cnt: 3;
unsigned cnt1: 4;
}three_bit_counter;
unsigned cnt;
void inccnt(void)
{
three_bit_counter.cnt++;
}
void inccnt1(void)
{
three_bit_counter.cnt1++;
}
void inccntmask(void)
{
unsigned tmp = cnt & 7;
tmp++;
tmp &= 7;
cnt &= ~7;
cnt |= tmp;
}
void inccnt1mask(void)
{
unsigned tmp = cnt & (0b1111 << 3) >> 3;
cnt &= ~(0b1111 << 3);
tmp++;
tmp &= 0b1111;
cnt |= tmp << 3;
}
使用位域对于避免依赖位域布局细节的代码而言,不会造成可移植性问题。
这些是相互冲突的问题,因为互操作性需要一致的布局,但依赖布局细节会导致可移植性问题。
位域在其他平台上是否也有类似的标准化?(我主要关心Linux(SysV ABI),MacOs和CygWin。)
一般来说,对于托管实现(包括您提到的所有示例),都会有一个平台ABI定义位域布局,用于软件在平台内的互操作性。ABI对于独立实现并不特别相关,但许多或者所有这样的实现确实会指定位域布局的完整细节。如果您关心的是是否可以链接使用不同C实现编译的具有位域的代码,并获得正确工作的程序,则答案几乎肯定是“是”。
struct ns_fn_cfg{unsigned flag1:1, flag2:1, flag3;}
)中,它们比要求用户或某些NS_FN_CFG_FLAG1|NS_FN_CFG_FLAG2|NS_FN_CFG_FLAG3
更好用,并且它们还具有比许多不是位域的_Bool
字段更好的调用方代码生成。) - Petr Skocik