在编写代码时,我在代码中观察到一件事,它与比特字段值与负整数的比较有关。
我有一个大小为1位的无符号结构成员和一个unsigned int。当我将负值与unsigned int变量进行比较时,我得到预期的结果为1但是当我将结构成员与负值进行比较时,我得到的结果相反为0。
#include <stdio.h>
struct S0
{
unsigned int bit : 1;
};
struct S0 s;
int main (void)
{
int negVal = -3;
unsigned int p = 123;
printf ("%d\n", (negVal > p)); /*Result as 1 */
printf ("%d\n", (negVal > s.bit));/*Result as 0 but expected 1 */
return 0;
}
我怀疑的是,如果我将负值与unsigned int进行比较,那么将发生平衡(隐式类型转换)。但是如果我比较unsigned int的结构成员为什么没有发生隐式类型转换。如果我错过任何基本的比特字段,请纠正我?
为了说明,以下使用32位int
和32位unsigned int
。
在negVal > p
:
negVal
是一个值为-3的int
。p
是一个价值123的unsigned int
。>
和其他关系运算符,告诉我们通常的算术转换是在操作数上执行的。int
,unsigned int
和比这些更宽的整数类型没有变化。对于其他整数类型,它表示:“如果int
可以表示原始类型的所有值(由宽度限制,对于位字段),该值将转换为int
;否则,它会被转换为unsigned int
。“negVal
是int
,因此整数促销不会改变。p
是unsigned int
,因此整数促销不会改变。int
和unsigned int
,int
被转换为unsigned int
。int
-3转换为unsigned int
导致4,294,967,293。 (转换被定义为将UINT_MAX + 1
,即4,294,967,296加上或减去该值,使其达到范围内所需的次数。这相当于“包裹”模4,294,967,296或重新解释-3的二进制补码表示为unsigned int
。)negVal > p
已成为4294967293u > 123u
。在negVal > s.bit
:
negVal
是一个值为-3的int
。s.bit
是一个位为0的位字段。negVal
是int
,因此整数促销不会改变。s.bit
是一个比int
更窄的位场,它将通过整数促销转换。这个一位的位字段可以表示0或1.这两个都可以用int
表示,因此规则“如果int
可以表示原始类型的所有值(由宽度限制,有点) -field),该值转换为int
“适用。int
会得到0。int
,因此不需要转换。negVal > s.bit
已成为-3 > 0
。(把我的评论作为答案)
gcc将s.bit
提升为int,所以(negVal > s.bit)
做(-3 > 0)
估值为0
请参阅Should bit-fields less than int in size be the subject of integral promotion?,但您的问题并不重复。
(negVal > p)
返回1,因为negVal被提升为unsigned产生一个很大的值,请参阅Signed/unsigned comparisons