1. I am unable to understand a couple of things. First, how can adding a signed and an unsigned number cast the enter result into unsigned type?
This is defined by integer promotions and integer conversion rank.
6.3.1.8 p1: Otherwise, if the operand that has unsigned integer type has rank greater or
equal to the rank of the type of the other operand, then the operand with
signed integer type is converted to the type of the operand with unsigned
integer type.
In this case unsigned has a higher rank than int, therefore int is promoted to unsigned.
The conversion of int ( -2 ) to unsigned is performed as described:
6.3.1.3 p2: Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or
subtracting one more than the maximum value that can be represented in the new type
until the value is in the range of the new type
2. If the result is indeed 0xFFFFFFFF of unsigned type, why in a 32 bit system, while adding it with ptr, will it be interpreted as ptr-1, given that the number is actually unsigned type and the leading 1 should not signify sign?
This is undefined behavior and should not be relied on, since C doesn't define pointer arithmetic overflow.
6.5.6 p8: If both the pointer
operand and the result point to elements of the same array object, or one past the last
element of the array object, the evaluation shall not produce an overflow; otherwise, the
behavior is undefined.
3. Second, why is the result different in 64 bit system?
( This assumes( as does the picture ) that int and unsigned are 4 bytes. )
The result of A and B is the same as described in 1., then that result is added to the pointer. Since the pointer is 8 bytes and assuming the addition doesn't overflow( it still could if ptr had a large address, giving the same undefined behavior as in 2. ) the result is an address.
This is undefined behavior because the pointer points way outside of the bounds of the array.