Because sizeof() is calculated after the preprocessor is run, so the information is not available for #if .
The sizeof operator yields the size in bytes of the operand, which can be an expression or the parenthesized name of a type.
It is a compile-time operator as it returns the size of any variable or a constant at the compilation time. The size, which is calculated by the sizeof() operator, is the amount of RAM occupied in the computer. Syntax of the sizeof() operator is given below: sizeof(data_type);
sizeof operator is compile time entity not runtime and don't need parenthesis like a function. When code is compiled then it replace the value with the size of that variable at compile time but in function after function gets execute then we will know the returning value.
sizeof
is not a function, it's an operator. The parentheses are not part of the operator's name.size_t
, which causes "the usual arithmetic conversions" in which -1
is converted to unsigned, in which case it's a very large number.Basically you're comparing 4 > 0xffffffffu
, or something close to that at least. See this question for details.
Unsigned and signed integer promotion (rather "usual arithmetic conversions", to be more precise). sizeof
yields a value of type size_t
, and when compared to an unsigned value (which size_t
is), -1 is promoted to that type, and overflows and becomes huge.
Unsigned integer overflow has well-defined behavior and is to be taken as modulo 2 ^ width
, where width
is the number of bits in the particular unsigned integer type. So, if you have a 32-bit wide size_t
and int
, for example, your comparison will be equivalent with
if (4 > 4294967295u)
which is obviously false.
sizeof(int)
and -1
.sizeof(int)
is of type size_t
, which is guaranteed to be an unsigned integer. In practice, size_t
will most likely be at least as big as unsigned int
on any system out there.-1
is of type int
, which is equivalent to signed int
.These state (C11 6.3.1.8):
...
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.
int
cannot fit all values of a size_t
.-1
is converted to an unsigned integer. In practice, size_t
is most likely equivalent to either unsigned int or unsigned long. Whatever happens when you store -1 in such a variable is implementation-defined behavior.0xFFFFFFFF
(the number of FF depends on the size of an int on the given system).4 > 0xFFFFFFFF
evaluates to false.Sizeof is an operator that results in an unsigned long int. Hence, when you compare unsigned long int with -1, which is stored as 0xffffffff
(size of int is 4 bytes).
-1 is signed integer by default. But, in comparison between signed int and unsigned int, the compiler goes with implicit typecasting of signed int to unsigned int. This results in unsigned -1 to be approximately equal to 4.6giga value.
Hence, the output is false
.
Just test this and see for yourself
#include <stdio.h>
main() {
unsigned int a=4;
int b = -1;
//this is what you're doing
printf("%u vs %u\n", a, (unsigned int)b);
//this is what you want to do instead
printf("%d vs %d\n", (int)a, b);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With