-2

I have a "C"code snippet as below

int32_t A = 5;
uint32_t B = 8;
if ( A >= B )
 {
   printf("Test");
 }

When i build this i received an remark/warning as "comparison between signed and unsigned operands.Can any one address this issue?

nisha
  • 69
  • 1
  • 7

2 Answers2

0

Everything is ok while A is positive and B is less than 2^31.

But, if A is less than 0, then unexpected behavior occurs.

A = -1, in memory it will be saved as 0xFFFFFFFF. B = 5, in memory it will be saved as 0x00000005.

When you do

if (A < B) {
    //Something, you are expecting to be here
}

Compiler will compare them as unsigned 32-bit integer and your if will be expanded to:

if (0xFFFFFFFF < 0x00000005) {
    //Do something, it will fail.
}

Compiler warns you about this possible problem.

Comparison operation on unsigned and signed integers

unalignedmemoryaccess
  • 7,246
  • 2
  • 25
  • 40
  • It's implementatation-defined how negative numbers are saved in memory. When you write `A < B` then there is a value conversion , `-1` is converted to `0xFFFFFFFF` (assuming 32-bit) regardless of the negative number representation. Now, systems usually use 2's complement in order that this conversion is a no-op. But there are non 2's comp systems. – M.M Jul 27 '17 at 09:39
0

Good, very good! You are reading and paying attention to your compiler warnings.

In your code:

int32_t A = 5;
uint32_t B = 8;

if ( A >= B )
{
   printf("Test");
}

You have 'A' as a signed int32_t value with min/max values of -2147483648/2147483647 and you have and unsigned uint32_t with min/max of 0/4294967295, respectively. The compiler generates the warning to guard against cases that are always true or false based on the types involved. Here A can never be greater than B for any values in the allowable range of B from 2147483648 - 4294967295. That whole swath of numbers will provide False regardless of the individual values involved.

Another great example would be if ( A < B ) which produces a TRUE for all values of A from -2147483648 - -1 because the unsigned type can never be less than zero.

The compiler warnings are there to warn that testing with these types may not provide valid comparisons for certain ranges of numbers -- that you might not have anticipated.

In the real world, if you know A is only holding values from 0 - 900, then you can simply tell the compiler that 1) you understand the warning and by your cast will 2) guarantee the values will provide valid tests, e.g.

int32_t A = 5;
uint32_t B = 8;

if (A >= 0 ) {
    if ( (uint32_t)A >= B )
       printf("Test");
}
else
    /* handle error */

If you cannot make the guarantees for 1) & 2), then it is time to go rewrite the code in a way you are not faced with the warning.

Two good things happened here. You had compiler warnings enabled, and you took the time to read and understand what the compiler was telling you. This will come up time and time again. Now you know how to approach a determination of what can/should be done.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85