11

C99 标准的第 6.3.1.1 节包含:

以下可以用在表达式中,只要可以使用intor unsigned int

_Bool[...] , int, signed int, or类型的位域unsigned int

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

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

我有以下程序:

struct S { unsigned f:32; } x = { 28349};

unsigned short us = 0xDC23L;

main(){
  int r = (x.f ^ ((short)-87)) >= us;
  printf("%d\n", r);
  return r;
}

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

4

2 回答 2

3

似乎标准委员会已经发现了这种歧义,因为当前的草案澄清了这句话:

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

于 2011-05-12T19:19:29.660 回答
1

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

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

于 2011-05-12T12:11:32.137 回答