位字段可移植性

我在这里读到位字段不可移植。 这是否意味着下面定义位字段的代码(从这里获取的代码)无法在某些机器上编译?

如果是这样,为什么呢?

#include  #include  /* define simple structure */ struct { unsigned int widthValidated; unsigned int heightValidated; } status1; /* define a structure with bit fields */ struct { unsigned int widthValidated : 1; unsigned int heightValidated : 1; } status2; int main( ) { printf( "Memory size occupied by status1 : %d\n", sizeof(status1)); printf( "Memory size occupied by status2 : %d\n", sizeof(status2)); return 0; } 

位字段是可移植的,因为它们是标准中规定的C语言的一部分( C11第6.7.2.1节)。 任何无法识别使用位域的代码的编译器都不符合标准。 对你的例子也没有什么可疑的,因为它所做的就是有位域存在。

他们可能的意思是,田地本身可能在地点和秩序上无法预测地包装(标准,前面的参考文献第11段允许)。 这意味着具有例如大小为4,12,13和3的四个位域的结构不一定占用32位,并且它们不一定按该顺序放置在结构内; 编译器可以将它们放在喜欢的位置。 这意味着不能将结构视为基础二进制对象的实际组件表示。

相比之下,手动应用于整数的位掩码恰好存在于放置它们的位置。 如果你定义屏蔽掉无符号整数的前4位,后12位等的掩码,那么“字段”实际上将按顺序和位置应用于位(假设你知道字节顺序,无论如何)。 这使得表示编译器无关。

即它们是便携式的,但它们所做的可能不一定正是一个人实际想要操纵个别位可能需要的东西。

位字段是标准语言function。 他们将在所有C编译器中编译。 从这个意义上说,它们是便携式的。 您的代码格式正确,并且将在所有C编译器中编译。

诸如“位字段不可移植”之类的语句通常意味着存储器中位字段的物理布局可能因实现而不同(即从一个编译器到另一个编译器)。 如果在不同的实现上编译,您可能从程序中获得不同的输出。 但是只有当代码依赖于具有位字段的对象的内存布局时(例如,如果您测量它们的大小,就像在程序中那样),程序行为的差异才会发生。

换句话说,说“位字段不可移植”与说int类型“不可移植”几乎是因为它可以在不同平台上具有不同的大小或在其内部表示中使用不同的字节序。

在C中, int必须至少为16位。因此,如果您希望在最大可移植代码中使用位域,则不能使用占用超过16位的位域。

C.11§6.7.2.1¶5:

位字段的类型应为_Boolsigned intunsigned int或其他实现定义类型的限定或非限定版本。

C.11§5.4.2.1¶1:

int类型对象的最大值
INT_MAX +32767 // 2 15 – 1
unsigned int类型的对象的unsigned int
UINT_MAX 65535 // 2 16 – 1