为什么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结构和联合说明符

位字段的类型应为_Boolsigned intunsigned 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 

所有人都宣布同样的事情,所以没有理由通过不同的方式来编写它来容易混淆。