【发布时间】:2011-08-24 01:30:33
【问题描述】:
C99 标准的第 6.3.1.1 节包含:
以下内容可用于 无论
int或 可以使用unsigned int:[...]
_Bool类型的位域,int、signed int或unsigned int。如果
int可以表示所有值 原始类型,值为 转换为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 的系统提交报告)
【问题讨论】:
-
(x.f ^ ((short)-87))在您的两个系统上的值是多少?另外,sizeof(short)是什么? -
@Oli 在两个系统上,
-28396如果用 %d 打印,4294938900如果用 %u 打印。我认为这实际上更多的是表达式应该被认为具有哪种类型的问题。sizeof(short)是 2,chars 有 8 位。 -
嗯,上面写着
represent all values of the original *type*我不太确定结果应该是什么。 “位域”整数类型绝对不是它们自己的类型,因此在此处输入只能指您在第二句中给出的类型。但是unsigned将永远是未签名的。我的理解是,首先将字段隐式转换为原始类型,然后应用提升规则。 -
@Jens 我完全同意:对我来说,“宽度为 31 的位域”不是一种类型。但是我不禁注意到,如果您将
32更改为31,我尝试的所有编译器(现在是clang 1.5 和gcc 4.2.1)都会使程序返回0,这表明它们将x.f提升为@987654346 @ 并进行签名>=比较。 -
我发现了两个在这种情况下仍然返回 1 的编译器:
pcc和tcc。gcc4.4、clang2.9、icc12.0 和 opencc 4.2.4 的行为与您描述的一样。不过既然后面都是模仿gcc的,这个大概就不多说了。
标签: c c99 bit-fields