4

This C code gives output "False" and the else block is executing.

The value of sizeof(int) is 4 but the value of sizeof(int) > -1 is 0.

I don't understand what is happening.

#include <stdio.h>
void main()
{
    if (sizeof(int) > -1 )
    {
       printf("True");
    }
    else
    {
        printf("False");
    }
    printf("\n%d", (sizeof(int)) ); //output: 4
    printf("\n%d", (sizeof(int) > -1) ); //output: 0
}
dreamcrash
  • 36,542
  • 23
  • 64
  • 87
Deepak Gautam
  • 603
  • 7
  • 13
  • 2
    Enable all compiler warnings. You should get some. – Andrew Henle Dec 30 '20 at 16:05
  • `sizeof (int) > -1` converts `-1` to unsigned and is the same as `sizeof (int) > 4294967295` – pmg Dec 30 '20 at 16:10
  • ok, -1 is converted to some MAX value due to the fact that sizeof (int) return "unsigned" type value. Right? – Deepak Gautam Dec 30 '20 at 16:24
  • 1
    If am not mistaken what happen is that -1 is 11111...1 in signed complement for 2, if you tell the compiler that it is unsigned, than 11111.....1 the last digit will not be 4294967295 – dreamcrash Dec 30 '20 at 16:28
  • Why it converts -1 to the equivalent? Why not it converts " sizeof(int) " to int type? – Deepak Gautam Dec 30 '20 at 16:32
  • Does this answer your question? [Why is −1 > sizeof(int)?](https://stackoverflow.com/questions/3100365/why-is-%e2%88%921-sizeofint) – phuclv Dec 30 '20 at 16:42
  • 1. [`void main()` is wrong](https://stackoverflow.com/q/204476/995714). 2. You have UB when printing `sizeof` with `%d`. You [must use `%zu` instead](https://stackoverflow.com/q/940087/995714). And there are lots of duplicates: [Why is (sizeof(int) > -1) false? (duplicate)](https://stackoverflow.com/q/34151309/995714) – phuclv Dec 30 '20 at 16:46
  • `void main()` is not wrong. Otherwise I have to write extra line `return 0`. – Deepak Gautam Dec 30 '20 at 17:14
  • 1
    @DeepakGautam it's wrong. It's only valid in some extensions like Turbo C or MSVC, or in a *freestanding* environment, otherwise it's completely forbidden. Read the other question for more info. And *Otherwise I have to write extra line `return 0`* is also **wrong**. In C99 a **`return 0` is implicitly added** if you don't write one. See [Why does main() not need a return statement? (duplicate)](https://stackoverflow.com/q/13232784/995714) – phuclv Jan 01 '21 at 16:09
  • yes I know, I forgot it. thanks @phuclv – Deepak Gautam Jan 05 '21 at 09:11

3 Answers3

7

Your sizeof(int) > -1 test is comparing two unsigned integers. This is because the sizeof operator returns a size_t value, which is of unsigned type, so the -1 value is converted to its 'equivalent' representation as an unsigned value, which will actually be the largest possible value for an unsigned int.

To fix this, you need to explicitly cast the sizeof value to a (signed) int:

    if ((int)sizeof(int) > -1) {
        printf("True");
    }
Adrian Mole
  • 30,672
  • 69
  • 32
  • 52
  • Why it converts -1 to the equivalent? Why not it converts " sizeof(int) " to int type? – Deepak Gautam Dec 30 '20 at 16:29
  • 2
    Because the rules say so: https://stackoverflow.com/questions/5416414/signed-unsigned-comparisons – abelenky Dec 30 '20 at 16:34
  • 2
    @abelenky Indeed (although that post is for C++). From [this C11 Draft Standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) (6.3.1.8): *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.* – Adrian Mole Dec 30 '20 at 16:37
  • so it's implicit behavior. Thanks @abelenky – Deepak Gautam Dec 30 '20 at 16:37
  • 2
    −1 is converted by value, not representation, to 2^N−1, where N is the number of bits in `size_t`. For example, −1 has different representations in two’s complement (111…111), one’s complement (111…110), and sign-and-magnitude (100…001), but `(size_t) -1` is always 2^N−1 per the C standard. Also note that `size_t` can be narrower than `int`, in which case it is promoted and the `-1` is not, and `sizeof(int) > -1` evaluates to true. – Eric Postpischil Dec 30 '20 at 19:57
  • @EricPostpischil You are correct (of course). Yet my proposed solution will work, even in the ***very*** rare case that `size_t` is narrower than `int` (although, then it will admittedly be superfluous). – Adrian Mole Dec 30 '20 at 20:54
3

The sizeof operator gives a size_t result.

And size_t is an unsigned type while -1 is not.

That leads to problem when converting -1 to the same type as size_t (-1 turns into a very large number, much larger than sizeof(int)).

Since sizeof returns an unsigned value (which by definition can't be negative), a comparison like yours makes no sense. And besides standard C doesn't allow zero-sized objects or types, so even sizof(any_type_or_expression) > 0 will always be true.

Some programmer dude
  • 363,249
  • 31
  • 351
  • 550
2

You have to be careful when mixing signed and unsigned values in expressions (and sizeof yields a size_t, which is unsigned).

In a fair number of cases (including this one) the compiler will convert both values to the same type before carrying out operations on them--and when you mix signed and unsigned values, that same type will usually be the unsigned type involved. So what happens in this case is that the -1 gets converted to an unsigned--and when converted to an unsigned value, -1 always converts to the largest value that unsigned type can hold.

From there, the rest is probably fairly clear, I'd guess.

Jerry Coffin
  • 437,173
  • 71
  • 570
  • 1,035