为什么C中的位字段需要定义类型unsigned int或signed int
我在我的C项目上运行代码质量检查,其涉及具有位字段的结构。 我遇到了一种情况,根据MISRA C 2004标准,规则#6.4 – 是一种违规,其内容如下:“6.4位字段只能被定义为unsigned int或signed int类型。” Microsoft Developer Network上提供的文献声明了这一点。 任何人都可以解释为什么bitfield成员的数据类型需要签名或无符号int? 为什么我不允许执行以下操作,即使以下代码编译时没有警告:
typedef struct { char a: 4; char b: 4; char flag: 1; }MY_STRUCT
主要原因是,如果您没有明确声明已signed
或未unsigned
,则除了通过阅读实现的定义之外,您不知道该类型是被视为有signed
还是unsigned
。 这意味着如果不使用带有显式signedness关键字的类型,就无法编写可移植代码。 (另请注意,对于位字段类型指示符使用char
是使用实现定义的类型。)
ISO / IEC 9899:2011 – §6.7.2.1结构和联合说明符
位字段的类型应为
_Bool
,signed int
,unsigned int
或其他实现定义类型的限定或非限定版本。…
位字段被解释为具有由指定位数组成的有符号或无符号整数类型。 125)
125)如上面6.7.2中所规定的,如果使用的实际类型说明符是
int
或定义为int
的typedef-name,则无论位字段是有符号还是无符号,它都是实现定义的。
这指的是:
§6.7.2类型说明符
¶4指定位域宽度的表达式应为整数常量表达式,其非负值不超过指定类型的对象的宽度,冒号和表达式省略。
¶5…除了对于位域,它是实现定义的,指定符
int
指定与signed int
相同的类型还是与unsigned int
相同的类型。
我没有写标准,所以我只能推测。
也就是说,我的猜测是,当宽度实际上没有差别时,使用不同宽度的整数类型会让人感到困惑(因为无论如何都指定了位数)。 例如:
char a : 4 short a : 4 int a : 4
所有人都宣布同样的事情,所以没有理由通过不同的方式来编写它来容易混淆。