Question: What's really happening here? The output now is "False":

```
#include <stdio.h>

int main()
{
     if (sizeof(int) > any_negative_integer)
         printf("True");
     else
         printf("False");
     return 0;
}

```

If I change it to:

```
if (sizeof(int) < any_negative_integer)

```

the output is "True".

Update: the [same question](https://stackoverflow.com/questions/17293749/sizeof-operator-in-if-statement) has already been asked, I could not find it before asking.

Answer: 
[sizeof](http://en.wikipedia.org/wiki/Sizeof) returns `size_t` which is unsigned and so `-1` is being converted to a very large unsigned number. Using the right warning level would have helped here, `clang` with the `-Wconversion` or `-Weverything`(*[note this is not for production use](https://softwareengineering.stackexchange.com/questions/122608/clang-warning-flags-for-objective-c-development/124574#124574)*) flags warns us:

```
warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion]
   if (sizeof(int) > -1)
                   ~ ^~

```

For `gcc` you receive a similar warning using the `-Wextra` flag:

```
warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    if (sizeof(int) > -1)
                    ^

```

For reference, we know *size\_t* is *unsigned* from the [draft C99 standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) section `7.17` *Common definitions*  which says:

```
 size_t

```

> 
> which is the unsigned integer type of the result of the sizeof operator;[...]
> 
> 
> 

Note, it does not specify anything else about the type, in my specific case it happens to be *unsigned long* but it does not have to be.

The conversion of `-1` is due to the *usual arithmetic conversion* covered in section `6.3.1.8` *Usual arithmetic conversions* which says:

> 
> [...]
> 
> 
> 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.
> 
> 
> Otherwise, if the type of the operand with signed integer type can represent
>  all of the values of the type of the operand with unsigned integer type, then
>  the operand with unsigned integer type is converted to the type of the
>  operand with signed integer type.
> 
> 
> Otherwise, both operands are converted to the unsigned integer type
>  corresponding to the type of the operand with signed integer type.
> 
> 
> 

So the only time `-1` would not be converted to an unsigned value would be if *int* could represent all the values of *size\_t*, which is not the case here.

Why `-1` ends up being a large unsigned value, actually it ends up being being the max value of the unsigned type is due to section `6.3.1.3` *Signed and unsigned integers* which says:

> 
> 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.49)
> 
> 
> 

So we end up with:

```
-1 + (UMAX + 1)

```

which is:

```
UMAX

```

and thus end up with:

```
if (sizeof(int) > UMAX )

```
Because `sizeof()` returns a `size_t`, an unsigned type. Comparing signed and unsigned types can give surprising results due to implicit casting before the comparison.