为什么C中的位字段需要定义为unsigned int或signed int类型

时间:2014-06-02 04:32:49

标签: c structure bit-fields

我在我的C项目上运行代码质量检查,该项目涉及具有位字段的结构。我遇到了一种情况,根据MISRA C 2004标准,规则#6.4 - 是一种违规行为,内容如下: “6.4位字段只能定义为unsigned int或signed int类型。” Microsoft Developer Network here上提供的文献声明了这一点。 任何人都可以解释为什么bitfield成员的数据类型需要签名或unsigned int?为什么我不允许执行以下操作,即使以下代码编译时没有警告:

typedef struct
{
    char a: 4;
    char b: 4;
    char flag: 1;
}MY_STRUCT

2 个答案:

答案 0 :(得分:4)

主要原因是,如果您未明确说明signedunsigned,则不知道该类型是否会被视为signedunsigned除了阅读实现对其功能的定义。这意味着如果不使用带有显式signedness关键字的类型,就无法编写可移植代码。 (另请注意,对于位字段类型指示符使用char正在使用实现定义的类型。)

ISO / IEC 9899:2011 - §6.7.2.1结构和联合说明符

  

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

     

...

     

位字段被解释为具有有符号或无符号整数类型   指定的位数。 125)

     

125)如上面6.7.2中所述,如果使用的实际类型说明符是int或typedef-name定义为int,   然后是实现定义位字段是有符号还是无符号。

指的是:

§6.7.2类型说明符

  

¶4指定位域宽度的表达式应为整数常量表达式,其非负值不超过指定类型的对象的宽度,冒号和表达式省略

     

¶5...除了对于位域,   它是实现定义的,说明符int是否指定了相同的类型   signed int或与unsigned int相同的类型。

答案 1 :(得分:0)

我没有写标准,所以我只能推测。

那就是说,我的推测是,当宽度实际上没有区别时(因为你指定了位数),使用不同宽度的整数类型会让人感到困惑。例如:

char a : 4
short a : 4
int a : 4

所有声明都是一样的,所以没有理由通过不同的写作方式来容易混淆。