无符号位域的类型:int或unsigned int

C99标准的第6.3.1.1节包含:

如果可以使用intunsigned int则可以在表达式中使用以下内容:

[…] _Boolintsigned intunsigned int类型的位字段。

如果int可以表示原始类型的所有值,则该值将转换为int ; 否则,它将转换为unsigned int

在我看来,这意味着unsigned int位字段被提升为int ,除非无符号位字段的宽度等于int的宽度,在这种情况下最后一个短语适用。

我有以下程序:

 struct S { unsigned f:32; } x = { 28349}; unsigned short us = 0xDC23L; main(){ int r = (xf ^ ((short)-87)) >= us; printf("%d\n", r); return r; } 

还有两个系统来执行这个程序( int在两个系统上都是32位)。 一个系统说这个程序打印1,另一个系统说它打印0.我的问题是,我应该在哪两个系统中提交错误报告? (我倾向于针对打印0的系统提交报告,因为上面的摘录)

标准委员会似乎已经发现了这种含糊不清的情况,因为目前的草案澄清了这句话:

如果int可以表示原始类型的所有值(由宽度限制,对于位字段),该值将转换为int;

我的读数和你一样:int的大小的无符号位域应该有unsigned int作为类型,小于它应该有signed int类型的int。

我访问的编译器(x86上的gcc,Sparc上的Sun CC,POWER上的IBM xlC)具有与此读数匹配的行为(在程序中打印1,如果位域减少到31位则打印0或签名)。