简体   繁体   English

无符号位字段值与有符号值的比较

[英]Comparison of Unsigned bit field value with signed values

while writing the code I observe one thing in my code its related to the comparison of bit-field value with negative integers. 在编写代码时,我在代码中观察到一件事,它与比特字段值与负整数的比较有关。

I have one structure member of unsigned of size one bit and one unsigned int. 我有一个大小为1位的无符号结构成员和一个unsigned int。 When I compare the negative value with unsigned int variable I am getting expected result as 1 but when I compare the structure member with the negative value I am getting the opposite result as 0. 当我将负值与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;
}

My doubt is if I compare the negative value with unsigned int then balancing will happen (implicit type casting). 我怀疑的是,如果我将负值与unsigned int进行比较,那么将发生平衡(隐式类型转换)。 But if I compare structure member of unsigned int why implicit type casting is not happening. 但是如果我比较unsigned int的结构成员为什么没有发生隐式类型转换。 Correct me if I miss any basics of bit fields? 如果我错过任何基本的比特字段,请纠正我?

(move my remark as an answer) (把我的评论作为答案)

gcc promotes s.bit to an int , so (negVal > s.bit) does (-3 > 0) valuing 0 gccs.bit提升为int ,因此(negVal > s.bit)确定(-3 > 0) 0

See Should bit-fields less than int in size be the subject of integral promotion? 请参阅大小小于int的位字段是否应该是整体提升的主题? but your question is not a duplicate of it. 但你的问题并不重复。


(negVal > p) returns 1 because negVal is promoted to unsigned producing a big value, see Signed/unsigned comparisons (negVal > p)返回1,因为negVal被提升为unsigned,产生一个很大的值,参见Signed / unsigned比较

For illustration, the following uses a 32-bit int and a 32-bit unsigned int . 为了便于说明,以下使用32位int和32位unsigned int

In negVal > p : negVal > p

  • negVal is an int with value −3. negVal是一个值为-3的int
  • p is an unsigned int with value 123. p是一个值为123的unsigned int
  • C 2018 6.5.8 3, which is discusses > and the other relational operators, tells us that the usual arithmetic conversions are performed on the operands. C 2018 6.5.8 3,讨论了>和其他关系运算符,告诉我们通常的算术转换是在操作数上执行的。
  • 6.3.1.8 1 defines the usual arithmetic conversions. 6.3.1.8 1定义了通常的算术转换。 For integer types, the first step of the usual arithmetic conversions is to perform the integer promotions on each operand. 对于整数类型,通常的算术转换的第一步是对每个操作数执行整数提升
  • 6.3.1.1 2 defines the integer promotions. 6.3.1.1 2定义整数提升。 int , unsigned int , and integer types wider than these are unchanged. intunsigned int和比这些更宽的整数类型不变。 For other integer types, it says: ”If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int ; 对于其他整数类型,它表示:“如果int可以表示原始类型的所有值(由宽度限制,对于位字段),该值将转换为int ; otherwise, it is converted to an unsigned int .” 否则,它将转换为unsigned int 。“
  • Since negVal is an int , it is unchanged by the integer promotions. 由于negVal是一个int ,因此整数提升不会改变它。
  • Since p is an unsigned int , it is unchanged by the integer promotions. 由于punsigned int ,因此整数提升不会改变它。
  • The next step in the usual arithmetic conversions is to convert one operand to the type of the other. 通常的算术转换的下一步是将一个操作数转换为另一个操作数的类型。 For int and unsigned int , the int is converted to unsigned int . 对于intunsigned intint将转换为unsigned int
  • Converting the int −3 to unsigned int results in 4,294,967,293. int -3转换为unsigned int产生4,294,967,293。 (The conversion is defined to add or subtracting UINT_MAX + 1 , which is 4,294,967,296, to the value as many times as necessary to bring it in range. This is equivalent to “wrapping” modulo 4,294,967,296 or to reinterpreting the two's complement representation of −3 as an unsigned int .) (转换定义为将UINT_MAX + 1 ,即4,294,967,296加上或减去该值,使其达到范围内所需的次数。这相当于“包装”模4,294,967,296或重新解释二的补码表示-3作为unsigned int 。)
  • After the conversions, the expression negVal > p has become 4294967293u > 123u . 转换后,表达式negVal > p变为4294967293u > 123u
  • This comparison is true, so the result is 1. 这种比较是正确的,结果是1。

In negVal > s.bit : negVal > s.bit

  • negVal is an int with value −3. negVal是一个值为-3的int
  • s.bit is a one-bit bit-field with value 0. s.bit是一位值为0的一位位字段。
  • As above, the usual arithmetic conversions are performed on the operands. 如上所述,对操作数执行通常的算术转换。
  • As above, the first step of the usual arithmetic conversions is to perform the integer promotions on each operand. 如上所述,通常的算术转换的第一步是对每个操作数执行整数提升。
  • Since negVal is an int , it is unchanged by the integer promotions. 由于negVal是一个int ,因此整数提升不会改变它。
  • Since s.bit is a bit-field narrower than an int , it will be converted by the integer promotions. 由于s.bit是比int更窄的位字段,因此它将由整数提升转换。 This one-bit bit-field can represent either 0 or 1. Both of these can be represented by an int , and therefore the rule “If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int ” applies. 这个一位的位字段可以表示0或1.这两个都可以用int表示,因此规则“如果int可以表示原始类型的所有值(由宽度限制,有点) -field),将值转换为intint ”。
  • Converting 0 to int results in 0. 将0转换为int导致0。
  • The next step in the usual arithmetic conversions would be to convert one operand to the type of the other. 通常的算术转换的下一步是将一个操作数转换为另一个操作数的类型。 Since both operands are now int , no conversion is needed. 由于两个操作数现在都是int ,因此不需要转换。
  • After the conversions, the expression negVal > s.bit has become -3 > 0 . 转换后,表达式negVal > s.bit已变为-3 > 0
  • This comparison is false, so the result is 0. 此比较为false,因此结果为0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM