This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
A riddle (in C)
Can someone please explain what is wrong with this code?
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
d <= (TOTAL_ELEMENTS-2)
d is signed: it is an int.
But TOTAL_ELEMENTS is unsigned: sizeof yields a size_t value and size_t is an unsigned type.
In the <= expression d is converted to an unsigned number by the way of the usual arithmetic conversions and it becomes a huge number.
When d is -1 and is compared with TOTAL_ELEMENTS-2 (which is size_t type, ie an unsigned integer), d is promoted to a large number in an unsigned type. Then, d is greater than TOTAL_ELEMENTS-2, so the loop is never executed.
c11
§ 6.5.8 Relational operators
If both of the operands have arithmetic type, the usual arithmetic conversions are
performed.
§ 6.3.1.8 Usual arithmetic conversions
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.
Related
This question already has an answer here:
Applying "not" operator on long double in C
(1 answer)
Closed 2 years ago.
I am trying to understand this code. Can anyone explain why sizeof(!a+b) equals 16? What datatype is returned, after this operation !a+b?
#include <stdio.h>
int main()
{
long double a;
long double b;
int arr[sizeof(!a + b)];
printf("%d", sizeof(arr));
}
The result of !a is integer. Integer + long double = long double.
sizeof(long double) in your implementation is 16.
int is 4 bytes long. sizeof 16 elements integer array is 16 * 4 = 64
!a returns int, per the C11 standard:
Section 6.5.3.3 "Unary arithmetic operators" paragraph 5:
The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0. The result has type int. The expression !E is equivalent to (0==E).
int + long double gives a long double. Again, from the C11 standard:
6.5.6 "Additive operators" paragraph 4
If both operands have arithmetic type, the usual arithmetic conversions are performed on them.
Looking deeper:
6.3.1.8 "Usual arithmetic conversions"
First, if the corresponding real type of either operand is long double, the other operand is converted, without change of type domain, to a type whose corresponding real type is long double.
The extra bits about type domains are in reference to compound types like complex.
In your implementation, sizeof(long double) is 16 (i.e. 128 bits). int is 4 bytes long. Therefore the size of the array is 4 * 16 = 64, which explains the output of your program.
I have below C code in which I have applied a not operator on a long double variable:
#include <stdio.h>
int main()
{
long double a;
signed char b;
int arr[sizeof(!a+b)];
printf("\n%d",sizeof(arr));
return 0;
}
This code outputs 16. I have problem in understanding what happenes when we apply not operator on long double, as we have done with a.
Please help me to understand whats happeneing with this code.
Thank You!
From the C Standard (6.5.3.3 Unary arithmetic operators)
5 The result of the logical negation operator ! is 0 if the value of
its operand compares unequal to 0, 1 if the value of its operand
compares equal to 0. The result has type int. The expression !E is
equivalent to (0==E).
So in this expression
sizeof(!a+b)
the sub-expression !a has the type int.
There are used the integer promotions of the operand b to the type int in the expression!a + b because the rank of the type signed char is less than the rank of the type int and the type int can represent all values of the type signed char.
From the C Standard (6.3.1.1 Boolean, characters, and integers)
...If an int can represent all values of the original type (as restricted
by the width, for a bit-field), the value is converted to an int;
otherwise, it is converted to an unsigned int. These are called the
integer promotions. 58) All other types are unchanged by the integer
promotions.
So the full expression is equivalent to
sizeof( int )
If the sizeof( int ) is equal to 4 then you have an array declared like
int arr[4];
Its size is equal to 16 that is to 4 * sizeof( int ).
This question already has answers here:
Comparison operation on unsigned and signed integers
(7 answers)
Closed 6 years ago.
Following snippet of code is not working as I expected, the output of the following program is "S is Bigger" when compiled with GCC in an Ubuntu machine. Although the variable s is -1 and which is clearly smaller than sizeof(buffer) which is 20. But still it prints S is Bigger.
Only logical assumption I can make is that C is converting the variable "s" to unsigned integer and using in "If" condition.
If My assumption is correct why C is doing that or if I am wrong why this snippet is giving this confusing output.
#include <stdio.h>
int main(void) {
int s = -1;
char buffer[20];
if(s > sizeof(buffer)){
printf("S is Bigger");
}
return 0;
}
From the answer to this question
It's safe provided the int is zero or positive. If it's negative, and size_t is of equal or higher rank than int, then the int will be converted to size_t and so its negative value will instead become a positive value.
sizeof() returns size_t
You are correct, the compiler converts s to the unsigned int data type size_t (which is the return value of sizeof operator). So the comparison become (on my system where size_t is 64 bit):
if (18446744073709551615 > 20)
which is clearly true ;)
This is part of the Implicit conversions defined by the standard. The relevant section is the "Usual arithmetic conversions" which is in 6.3.1.8 of the standard.
See also this post and this other post
Foundamental rules:
If both operands have the same type, no further conversion is needed.
If both operands are of the same integer type (signed or unsigned), the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
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.
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, 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.
This question already has answers here:
Comparison operation on unsigned and signed integers
(7 answers)
Closed 7 years ago.
#include<stdio.h>
int main(){
unsigned int a = 6;
int b = -20;
( a+b > 6 ) ? puts( "a") : puts( "b");// if a+b > 6 then a else b
}
I presumed that the output should be "b" but it wasn't.
output: a
C99 standard, section 6.3.1.8
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.
So here b(value= -20) is converted to unsigned type (a large value), it will be equivalent to -
( a+(unsigned int)b > 6 )
Therefore , output is a not b
The type of the expression a + b is unsigned int, which is the result of arithmetic conversions that are applied whenever the arithmetic operators are used on operands of different types. Each operand is first converted to this common type, and the result of converting -20 to an unsigned int is a very large value.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
A riddle (in C)
see this code
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= TOTAL_ELEMENTS-2;d++)
printf("%d\n",array[d+1]);
return 0;
}
now this loop won't run.
sizeof() would return an unsigned value so TOTAL_ELEMENTS has an unsigned value.
now , coming to the for loop, please tell me if the unary operator '-' works on signed int 2 or an implicit conversion takes place into unsigned and then the '-' operator works.
In your example d is converted to an unsigned int in the comparison. But -1 cannot be represented as an unsigned int value, so it is is converted to UINT_ MAX. To avoid this behaviour you can convert the right side of the comparison to an signed int by prepending (int).
See Understand integer conversion rules for details on integer conversion in C.
There's no unary operator in d <= TOTAL_ELEMENTS-2.
The TOTAL_ELEMENTS-2 reduces to an expression with a binary operator of -. This expression then becomes unsigned because one of its operands is unsigned.
In the case of d <= TOTAL_ELEMENTS-2, d's type is also converted to unsigned int for the same reason.
The relevant portion of the standard is section 6.3.1.8#1 (ISO/IEC 9899:1999) 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."
Yes, d also has an unsigned type in that expression, because of promotion, which is why the loop fails.
However, the question is whether the C compiler "thinks":
(unsigned) ((unsigned) 5 - (unsigned) 2)
i.e. promoting 2 to unsigned, or:
(unsigned) ((unsigned) 5 - (signed) 2)
i.e. subtraction taking operands of both types. Of course, it doesn't matter, as it would be the same operation for both. However, the whole point is that subtracting will return a value of one type, so theoretically it can only take arguments of that type. So it's the first (unsigned int 2).
P.S. (-2) is unary, while (5 - 2) is binary.
I suspect the unsigned type of sizeof() to propagate to the expression TOTAL_ELEMENTS-2 and then to both operands of d <= TOTAL_ELEMENTS-2. Inserting (int) juste before TOTAL_ELEMENTS fixes the issue.
look , that '-' operator being unary was a stupid thing.forget it.it was the binary '-' , i realise.
when 2 is converted to unsigned int it becomes unsigned 2 , so TOTAL_ELEMENTS-2 has a value equal to unsigned 5 , and then when d is being converted to an unsigned int it gets a large positive value and
so the loop fails.
is that happening here??
and yes, i didn't write this code,this is some c puzzle i found on the web.
thank ya all.