Relational operators evaluation result - c

Assume we have an expression like
(x > 5)
in C language. Is there any guarantee given by the language / standard that the expression will be evaluated to 0 when it's false and to 1 when it's true?

Yes, it is guaranteed by the standard.
As per the C11 standard document, chapter 6.5.8, paragraph 6, [Relational operators]
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >=
(greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is
false. The result has type int.
Update: Same chapter and paragraph for C99 standard also.

In gcc, it will be evaluated as one and zero.
Consider following program
#include <stdio.h>
int main(void)
{
int a = 3;
int b = 4;
if((a > b) == 0)
printf("a > b is false\n");
if((a < b) == 1)
printf("a < b is true\n");
return 0;
}
It gives output
a > b is false
a < b is true

Related

how does c evaluate less than and more than expretion? [duplicate]

This question already has answers here:
Chaining multiple greater than/less than operators
(6 answers)
Closed 9 months ago.
I would like to know how i is evaluated in this code in C language ?
int x = 10, y = 20, z = 5, i;
i = x < y < z;
printf("%d\n",i);
The result of a relational operator is either integer 1 if the condition is true or 0 otherwise. And relational operators evaluates from left to right.
So this statement
i = x < y < z;
is equivalent to
i = ( x < y ) < z;
and as x is less than y then it can be also rewritten like
i = 1 < z;
that initialize the variable i by 1 because 1 is less than 5.
From the C Standard (6.5.8 Relational operators)
6 Each of the operators < (less than), > (greater than), <= (less than
or equal to), and >= (greater than or equal to) shall yield 1 if the
specified relation is true and 0 if it is false.107) The result has
type int.
If you will rewrite the statement like
i = x < y && y < z;
then the result of the expression will be equal to 0 because y is not less than z.

How exactly does the ?: operator work in C?

I have a question, how the compiler operate on the following code:
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d = (b == c++) ? (c+1) : (c-1);
printf("d = %i\n", d);
}
I am not sure why the result is ‍‍‍d = 11.
In int d = (b == c++) ? (c+1) : (c-1);:
The value of c++ is the current value of c, 11. Separately, c is incremented to 12.
b == 11 is false, since b is 12.
Since (b == c++) is false, (c-1) is used. Also, the increment of c to 12 must be completed by this point.
Since c is 12, c-1 is 11.
d is initialized to that value, 11.
According to the C Standard (6.5.15 Conditional operator)
4 The first operand is evaluated; there is a sequence point between
its evaluation and the evaluation of the second or third operand
(whichever is evaluated). The second operand is evaluated only if the
first compares unequal to 0; the third operand is evaluated only if
the first compares equal to 0; the result is the value of the second
or third operand (whichever is evaluated), converted to the type
described below.110)
So in the initializing expression of this declaration
int d = (b == c++) ? (c+1) : (c-1);
the variable b is compared with the value of the variable c because the post-increment operator returns the value of its operand before incrementing it.
As the values are not equal each other (b is set to 12 while c is set to 11) then the sub-expression (c-1) is evaluated.
According to the quote there is a sequence point after evaluation of the condition of the operator. It means that after evaluation of the condition c has the value 12 after applying the post-increment operator to the variable c. As a result the variable d is initialized by the value 1 (12 - 1).
Translated to a regular if-statement your code would look like this:
int b=12, c=11;
int d;
if (b == c++)
d = c+1;
else
d = c-1;
The clue here is that c is incremented after the condition is checked. So you enter the else state but c already has the value 12 there.
Beacuse the condition is false, therefore the false case will happen: c-1, but since you incremented c in the condition by c++, therefore c is now 12. The result thus 12 - 1 which is 11.
EDIT:
What OP misunderstood was the post increment.
So what actually happen is like this:
#include<stdio.h>
int main(void)
{
int b=12, c=11;
int d;
if (b == c) { // 12 == 11 ? -> false
c = c + 1;
d = c + 1;
} else { // this executes since condition is false
c = c + 1; // post increment -> c++ -> c = 12 now
d = c - 1; // 12 - 1 = 11 -> d = 11
}
printf("d = %i\n", d);
}
Refer to Ternary Operator.
Syntax
condition ? value_if_true : value_if_false
So, you wrote
int d = (b == c++) ? (c+1) : (c-1);
In this situation, the result will be 11 because, after if checks, 'c' value is increased(c+1=12) and only after that it sets 'd' value as c(12)-1 which is 11.
If you used, for example:
int d = (b == ++c) ? (c+1) : (c-1);
"c" value would be increased before checking the statement, so it would be true and "d" value would be c(12)+1 which is 13.

Does "true" in C always mean 1?

Please consider these piece of C code:
if ((value & 1) == 1)
{
}
Assuming value equals 1, will (value & 1) return 1 or any unspecified non zero number?
§6.5.8 Relational operators
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.) The result has type int.
§6.5.9 Equality operators
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
§6.5.13 Logical AND operator
The && operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
§6.5.14 Logical OR operator
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
Does “true” in C always mean 1?
No. Any expression that evaluates to a non-zero value is "true" in C. For example,
if (-1) {
}
if (5-10) {
}
if( "string literal") {
}
are all "true" and pass the condition.
In your specific example, the relational operator == yields 1 which is also "true"(the same holds for all other relational operators as noted by Govind).
If you are really asking about whether the bit-wise AND (&) yields 1 when value is 1, then yes, value & 1 yields 1 (assuming value is an integer type -- & operator requires its operands to be integers).
In fact, you can probably try to understand the individual parts and (generally how the & and == operators behave) by using a simple program:
#include <stdio.h>
int main(void)
{
int value = 1;
printf(" value & 1 = %d\n", value & 1);
printf(" 2 & 1 = %d\n", 2 & 1);
printf("((value & 1) == 1) = %d", (value & 1) == 1);
}

Condition return value in C99

I am trying to optimize some code and I was wondering if the return value of a condition like
(1>0)
is always 1 in c99 ? I couldn't find the answer on the web and the few tests I made with gcc seems to indicate this is true. But is this part of the langage specification ?
The exact code (marching squares algorithm) :
to_run->data[(y / 2) * (my_grid->width / 2) + (x / 2)] =
(up[0] > level) +
(up[1] > level) << 1 +
(down[0] > level) << 2 +
(down[1] > level) << 3;
Yes.
C99 §6.5.8 Relational operators
Each of the operators < (less than), > (greater than), <= (less than or equal to), and >= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false. The result has type int
Yes.
The draft C99 spec says:
Each of the operators < (less than), > (greater than), <= (less than or equal to), and
>= (greater than or equal to) shall yield 1 if the specified relation is true and 0 if it
is false. The result has type int.

How come j is not incremented in this example?

C newbie here, and I'm wondering, how come j is not incremented in the example below?
I searched everywhere for an explanation
int i, j, k;
i = 3; j=4; k=5;
_Bool checkbit;
checkbit = i < j || ++j < k;
printf("%d\n", checkbit );
printf("%d %d %d\n", i, j , k);
The output is
1
3 4 5
instead of
1
3 5 5
Thanks!
Because it doesn't need to be evaluated.
checkbit = i < j || ++j < k;
i < j will yield true, so no matter what the second part of the expression yields, the value of checkbit will be true. Thus, it doesn't even bother evaluating it.
Just for kicks:
checkbit = i > j && ++j < k;
In this case, the second expression will not be evaluated because false && (expr) is false.
Double-Or is "Shortcutting" - it won't evaluate the rest of the expression if the first part is true.
Use a single-or to increment it whatever happens.
This can be useful sometimes. It speeds up execution, because if the first part is true, you know the result of the or must be true!
Note that this is the same (in reverse) for &&: If the first part of && is false, then the second part is ignored, as you know the result will be false.
And it's perhaps worth mentioning that this behavior, short-circuit evaluation, is in the C standard:
6.5.14 Logical OR operator
Syntax
1 logical-OR-expression:
logical-AND-expression
logical-OR-expression || logical-AND-expression
Constraints
2 Each of the operands shall have scalar type.
Semantics
3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it
yields 0. The result has type int.
4 Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is
a sequence point after the evaluation of the first operand. If the first operand compares
unequal to 0, the second operand is not evaluated.
(emphasis mine)
When using || operator, and the first condition evaluates to true, it ignores the rest unlike the && operator
checkbit = i < j || ++j < k; //since i < j is true, it skips over ++j < k

Resources