我读here位字段不可移植。这是否意味着下面的代码定义位字段(代码来自here)无法在某些机器上编译?
如果是这样,为什么呢?
#include <stdio.h>
#include <string.h>
/* 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;
}
答案 0 :(得分:20)
比特字段是可移植的,因为它们是标准(C11部分6.7.2.1)中指定的C语言的一部分。任何无法识别使用位域的代码的编译器都不符合标准。对你的例子也没有什么可疑的,因为它只是有位域存在。
它们可能意味着字段本身可能在位置和顺序上无法预测地包装(标准,前面的参考文献第11段允许)。这意味着一个结构,例如,大小为4,12,13和3的四个位域不一定占用32位,并且它们不一定按照该顺序放在结构中;编译器可以将它们放在喜欢的位置。这意味着不能将结构视为基础二进制对象的实际组件表示。
相比之下,手动应用于整数的位掩码恰好存在于放置它们的位置。如果你定义掩盖了无符号整数的前4位,后12位等的掩码,那么&#34;字段&#34;将实际应用于位,按顺序和位置(假设您知道字节顺序,无论如何)。这使得表示编译器无关。
即。它们是便携式的,但它们所做的可能不一定是一个人真正想要操纵个别位的东西。
答案 1 :(得分:9)
位字段是标准语言功能。他们将在所有C编译器中编译。从这个意义上说,它们是便携式的。您的代码格式正确,并且将在所有C编译器中编译。
&#34;比特字段等语句不可移植&#34;通常意味着存储器中位域的物理布局可能因实现而不同(即从一个编译器到另一个编译器)。如果在不同的实现上编译,您可能从程序中获得不同的输出。但只有在代码依赖于具有位字段的对象的内存布局时(例如,如果您测量它们的大小,就像在程序中一样),程序行为的差异才会发生。
换句话说,&#34;位字段不可移植&#34;与int
类型&#34;不可移植&#34;类似的几乎是一样的。仅仅因为它在不同平台上可以有不同的大小,或者在其内部表示中使用不同的字节序。
答案 2 :(得分:3)
{C}要求int
至少为16位。因此,如果您希望在最大可移植代码中使用位字段,则不能使用占位超过16位的位字段。 / p>
C.11§6.7.2.1¶5:
位字段的类型应为
_Bool
,signed int
,unsigned int
或其他实现定义类型的合格或非限定版本。
C.11§5.4.2.1¶1:
- 类型
int
的对象的最大值
INT_MAX +32767 //
2 15 - 1
- 类型unsigned int
的对象的最大值
UINT_MAX 65535 //
2 16 - 1