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. 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.
#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). But if I compare structure member of unsigned int why implicit type casting is not happening. 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
See Should bit-fields less than int in size be the subject of integral promotion? 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
For illustration, the following uses a 32-bit int
and a 32-bit unsigned int
.
In negVal > p
:
negVal
is an int
with value −3.p
is an unsigned int
with value 123.>
and the other relational operators, tells us that the usual arithmetic conversions are performed on the operands.int
, unsigned int
, and integer types wider than these are unchanged. 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
; otherwise, it is converted to an unsigned int
.”negVal
is an int
, it is unchanged by the integer promotions.p
is an unsigned int
, it is unchanged by the integer promotions.int
and unsigned int
, the int
is converted to unsigned int
.int
−3 to unsigned int
results in 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
.)negVal > p
has become 4294967293u > 123u
.In negVal > s.bit
:
negVal
is an int
with value −3.s.bit
is a one-bit bit-field with value 0.negVal
is an int
, it is unchanged by the integer promotions.s.bit
is a bit-field narrower than an int
, it will be converted by the integer promotions. 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.int
results in 0.int
, no conversion is needed.negVal > s.bit
has become -3 > 0
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With