8

Playing with some sources found code like this:

void foo(unsigned int i)
{
 if(i<0)
     printf("Less then zero\n");
 else
     printf("greater or equ\n");
}

int main()
{
    int bar = -2;
    foo(bar);
    return 0;
}

I think there is no sense, but may be there some cases(security?) that makes this check sensable?

wap26
  • 2,180
  • 1
  • 17
  • 32
dtoch
  • 185
  • 1
  • 2
  • 12
  • Thanks for your answers! You have strengthened my confidence. But someone wrote this. May be there some platforms or compilers which think another way? – dtoch Jun 21 '12 at 15:14
  • There may be some slight variation of the exact values for signed/unsigned conversions depending on the size of an int on your system (see the answers linked to by jonnyGold and wap26). But all compilers will output executables that exhibit the same control flow behavior in this case. In other words-- no :) Whoever wrote this probably didn't notice that this control flow situation would occur (a bug) or else they were experimenting. – erapert Jun 21 '12 at 15:22
  • Seems like you're right. I did some checks. gcc just removes any checks and write string: `foo: pushl %ebp movl %esp, %ebp subl $24, %esp movl $.LC0, (%esp) call puts leave ret` Clang generates check, but: 1. void foo(unsigned int i) inline `foo+19: jae 0x804841f ` 2. void foo(signed int i): inline `foo+19: jge 0x804841f ` – dtoch Jun 21 '12 at 15:33

2 Answers2

13

An unsigned int cannot be less than 0 by definition. So, to more directly answer your question, you're right in thinking that this makes no sense. It is not a meaningful security item either unless you encounter something like a loop that accidently decrements a signed int past 0 and then casts it as an unsigned int for use as an index into an array and therefore indexes memory outside of the array.

erapert
  • 1,383
  • 11
  • 15
  • 1
    [This answer](http://stackoverflow.com/questions/50605/signed-to-unsigned-conversion-in-c-is-it-always-safe) sheds light on what happens when you cast from a negative-valued int to an unsigned int. – bluevector Jun 21 '12 at 15:03
2

i will always be >=0because it is declared as unsigned and thus interpreted as an unsigned integer. So your first test will always be false.

Your call foo(bar) actually converts an int into an unsigned int. This may be what confuses you. And "conversion" does not actually change the bytes/bits value of your integer, it is just a matter of formal typing and interpretation.

See this answer for examples of signed/unsigned conversions.

Here is a simple example (the exact output depends on the number of bytes of an unsigned inton your system, for me it is 4 bytes).

Code:

printf("%u\n", (unsigned int) -2);

Output:

4294967294
Community
  • 1
  • 1
wap26
  • 2,180
  • 1
  • 17
  • 32