Why is (sizeof(int) > -1) false? [duplicate] - c

This question already has answers here:
Why should be there the involvement of type promotion in this code?
(1 answer)
Comparison operation on unsigned and signed integers
(7 answers)
Closed 7 years ago.
Can You justify the below code:
#include<stdio.h>
int main()
{
if(sizeof(int) > -1)
{
printf("\nTrue\n");
}
else
{
printf("\nFALSE\n");
}
}
The output is FALSE .....suggest me the reason

sizeof(int) has type size_t, which is an unsigned integer type.
-1 has type int, which is a signed integer type.
When comparing a signed integer with an unsigned integer, first the signed integer is converted to unsigned, then the comparison is performed with two unsigned integers.
sizeof(int) > (unsigned int)-1 is false, because (unsigned int)-1 is a very large number on most implementations (equal to UINT_MAX, or the largest number which fits in an unsigned int).

sizeof
yields a value of an unsigned type (namely size_t).
In sizeof(int) > -1 expression, the usual arithmetic conversion applies and -1 is converted to the unsigned type of sizeof which results in a huge unsigned value greater than -1.

It's because the sizeof operator returns an unsigned integer type. When compared with a signed integer type, the signed integer is converted to unsigned. So in effect, you were comparing sizeof(int) against the largest possible unsigned integer.
You can force the size to signed by casting:
#include <stdio.h>
int main()
{
if((int)sizeof(int) > -1)
{
printf("\nTrue\n");
}
else
{
printf("\nFALSE\n");
}
}

Related

why sizeof type compared with integer returns false [duplicate]

This question already has answers here:
sizeof() operator in if-statement
(5 answers)
Why is sizeof(int) less than -1? [duplicate]
(3 answers)
void main() { if(sizeof(int) > -1) printf("true"); else printf("false"); ; [duplicate]
(3 answers)
Why does this if condition fail for comparison of negative and positive integers [duplicate]
(6 answers)
Closed 4 years ago.
one strange behaviour I noticed in below code.
#include<stdio.h>
#include <stdbool.h>
int main()
{
int x = sizeof(int) > -1;
bool z = sizeof(int);
printf("x is %d \t z is %d \n",x,z);
if(sizeof(int)>-1)
{
printf("true\n");
}
else
printf("false\n");
}
Why int x is zero when sizeof(int) > -1 is true and the expected output should be 1.
GCC compiler Warning say's :
prog.c: In function 'main':
prog.c:6:21: warning: comparison of integer expressions of different signedness: 'long unsigned int' and 'int' [-Wsign-compare]
int x = sizeof(int) > -1;
^
prog.c:11:15: warning: comparison of integer expressions of different signedness: 'long unsigned int' and 'int' [-Wsign-compare]
if(sizeof(int)>-1)
So, you are comparing a signed int and an unsigned long int. When -1 is converted to unsigned long int the result is the maximal possible unsigned long int value (same as ULONG_MAX).
C $6.3.1.3, paragraph 2:
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.
For more information, read cppreference.
The sizeof operator yields not an int but size_t which is an unsigned integer type. When you compare a signed integer like -1 to an unsigned integer you will end up comparing the wrong values.
Do the following changes and the code will work as expected.
#include<stdio.h>
#include <stdbool.h>
int main()
{
int x = (int)sizeof(int) > -1;
bool z = sizeof(int);
printf("x is %d \t z is %d \n",x,z);
if((int)sizeof(int) > -1)
{
printf("true\n");
}
else
printf("false\n");
}
Output:
x is 1 z is 1
true
sizeof operator returns a type of size_t
The size_t type is an unsigned type. usually unsigned int
If you compare an unsigned int with -1 then by the integer promotion rules (Signed to unsigned conversion in C - is it always safe?), both of them will be converted to unsigned.
So -1 will be converted to 65535 and the equation 4>65535 will result in zero.
Difference between signed and unsigned integer types (which includes char) is that negative values are represented by most significant bit set to 1. On most platform the magnitude is represented by binary complement in that case. E.g. for char:
10000001: -(1)0000000 * 01111111 = -127
We should take 00000001, substract 1 from it and invert all bits except sign to get the value.
Now, during comparison signed values treated as unsigned, if other argument is unsigned. There are historical and practical reasons for that, e.g. to avoid ambiguity in character comparison when compiling legacy code. Traditionally all string in C were char* not unsigned char*.
10000001 as unsigned char equals to 129.
So, according to this program -1 is greater than 1.
#include <iostream>
int a = -1;
unsigned int b = 1;
int main(int argc, char** argv)
{
if(b < a) std::cout << "The world is mad.\n";
if(a > b) std::cout << "Yes, it is.\n";
return 0;
}
You always should look out for warning about comparison as well as about "possible data loss". Those are very common source of bug in programs.

C programming: Division in an if-statement [duplicate]

This question already has answers here:
My computer thinks that signed int is smaller then -1? [duplicate]
(3 answers)
sizeof() operator in if-statement
(5 answers)
Closed 5 years ago.
Why does it print 2 when the value of SIZE is greater than -1?
Link to the code: http://ideone.com/VCdrKy
#include <stdio.h>
int array[] = {1,2,3,4,5,6,7,8};
#define SIZE (sizeof(array)/sizeof(int))
int main(void) {
if(-1<=SIZE) printf("1");
else printf("2");
return 0;
}
Both arguments are in different type
Argument are 'converted' to 'common' type, and 'common' between signed -1 and unsigned SIZE is unsigned.
So -1 is converted -> 0xfffffff (depends on architecture) that is grater than SIZE
From the C standard on integer conversions:
If the operand that has unsigned integer type has rank greater than
or equal to the rank of the type of the other operand, the operand
with signed integer type is converted to the type of the operand with
unsigned integer type.
Here -1 is of type int, and SIZE is of type size_t. On your c compiler, size_t is unsigned and has greater than or equal rank to int, so the -1 is converted to size_t, which gives a large positive number (SIZE_MAX)

Why x is promoted to unsigned int? [duplicate]

This question already has answers here:
Why is a negative int greater than unsigned int? [duplicate]
(6 answers)
Closed 5 years ago.
Given that code :
int main(void) {
long x = -1;
if (x < sizeof(x)) {
printf("OK\n");
}
else {
printf("Not Ok\n");
}
return 0;
}
Prints:
Not Ok
I have read about usual arithmetic conversions, and from what i understood that if we have a comparison between two operands with different data types, the compiler invokes a data coercion on the operand which is narrower than the other operand, which will convert the the sizeof(x) into unsigned int to match the other operand, any thoughts?
Aside question:
I tried to do casting size(x) as int in the comparison expression as:
if(x < (int) size(x))
It prints Ok, which I find very strange!
You should never compare a signed number to an unsigned number. Add a compiler switch to warn you about this.
Here, in your case, x will be converted to unsigned, -1 becomes SIZE_MAX (the largest number a that std::size_t can hold). It is because sizeof returns an unsigned number (it returns std::size_t, which is unsigned)
The other thing that could happen, but don't happen in practice is that if sizeof(long)>sizeof(std::size_t) then sizeof(x) would be converted to long, so your program would print OK.

Comparision between a signed/unsigned value with a negative value

Program 1:
#include <stdio.h>
int main()
{
if (sizeof(int) > -1)
printf("Yes");
else
printf("No");
return 0;
}
Output : No
Program 2:
#include <stdio.h>
int main()
{
if (2 > -1)
printf("Yes");
else
printf("No");
return 0;
}
Output: Yes
Questions:
What is the difference between program 1 and program 2?
Why sizeof(int) is considered as unsigned?
Why is 2 in program 2 considered as signed?
It is common issue with usual arithmetic conversions between signed and unsigned integers. The sizeof operator returns value of type size_t, that is some implementation-defined unsigned integer type, defined in <stddef.h> (see also this answer).
Integer constant -1 is of type int. When size_t is implemented as "at least" unsigned int (which is very likely to happen in your case), then both operands of binary operator < are converted to unsigned type. Unsigned value cannot be negative, hence -1 is conveted into a large number.
The type of the value returned by the sizeof operator is size_t, which is specified to be an unsigned type (often equivalent to unsigned long).
Simple plain integer literals, like 2 or -1 are always of type int, and int is signed.
If you want an unsigned integer literal, you have to add the U suffix, like 2U.
This is because the sizeof operator returns a value in size_t. This is supposed to be an unsigned type, often implemented as unsigned int.
The number 2 by itself is an int, not unsigned int.

unsigned variable is behaving like signed [duplicate]

This question already has answers here:
Comparison operation on unsigned and signed integers
(7 answers)
In a C expression where unsigned int and signed int are present, which type will be promoted to what type?
(2 answers)
Closed 7 years ago.
This is the code,
#include <stdio.h>
int main()
{
unsigned int i = 0xFFFFFFFF;
if (i == -1)
printf("signed variable\n");
else
printf("unsigned variable\n");
return 0;
}
This is the output,
signed variable
Why is i's value -1 even it is declared as unsigned?
Is it something related to implicit type conversations?
This is the build environment,
Ubuntu 14.04, GCC 4.8.2
The == operator causes its operands to be promoted to a common type according to C's promotion rules. Converting -1 to unsigned yields UINT_MAX.
i's value is 0xFFFFFFFF, which is exactly the same as -1, at least when the later is converted to an unsigned integer. And this is exactly what is happening with the comparison operators:
If both of the operands have arithmetic type, the usual arithmetic conversions are performed. [...]
[N1570 $6.5.9/4]
-1 in two's complement is "all bits set", which is also what 0xFFFFFFFF for an unsigned int (of size 4) is.

Resources