iambrj
iambrj

Reputation: 71

returns true for ((unsigned int)0-1)>0

I came across some c++ code which was like

if(((unsigned int)0-1)>0)
{
//do something
}

and the program executed the statements in the if block. Being curious, I tried the same in c, which did the same. My understanding is that the statements in the if block get executed if the expression in the if condition returns a bool value true. This means that ((unsigned int)0-1)>0 must be returning true. Why is this happening?

Upvotes: 0

Views: 2613

Answers (2)

David Hammen
David Hammen

Reputation: 33116

if(((unsigned int)0-1)>0)

With ordinary arithmetic, 0-1 is negative one, which is not greater than zero. We're not dealing with ordinary arithmetic here.

The C++ (and also C) precedence rules says that casting has precedence over subtraction, so (unsigned int)0-1 is equivalent to ((unsigned int) 0)-1. In other words, the 0 is treated as an unsigned int.

Next in line we have an unsigned int minus a signed int. The C++ (and C) rules regarding such operations is that the signed value is treated as if it were unsigned. The C++ (and C) rules with regard to unsigned operations is to perform the computation modulo 2N, where N is the number of bits in the common type (typically 32 for an int, but no guarantee of that). 0-1 modulo 2N is 2N-1, which is a (large) positive number.

Quoting from the standard, [basic.fundamental] paragraph 4,

Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.46

and the footnote:

46) This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.

Upvotes: 2

songyuanyao
songyuanyao

Reputation: 172924

For (unsigned int)0-1, the operands of operator- is unsigned int 0 and int 1. Then the type of the result (i.e. the common type) would be unsigned int.

Otherwise, if the unsigned operand's conversion rank is greater or equal to the conversion rank of the signed operand, the signed operand is converted to the unsigned operand's type.

For unsigned int, it couldn't be 0-1, but

Unsigned integer arithmetic is always performed modulo 2n where n is the number of bits in that particular integer. E.g. for unsigned int, adding one to UINT_MAX gives ​0​, and subtracting one from ​0​ gives UINT_MAX.

That means if(((unsigned int)0-1)>0) is equivalent to if(UINT_MAX>0), which is true.

Upvotes: 5

Related Questions