Return value of "==" operator in C - c

Can I assume that in C, the "==" operator will always evaluate to 1 if the two values are equal or it can evaluate to other "true" values?
struct ss {
int id;
};
struct os {
int sid;
int state;
};
int count(struct ss *s, int state)
{
int num = 0;
// foreach o (of type os*) in a hash table
num += o->state == state && (s ? o->sid == s->id : 1);
return num;
}
So o->sid == s->id will return always 1 or 0, or it can return other values?

Can I assume that in C, the "==" operator will always evaluate to 1 if the two values are equal or it can evaluate to other "true" values?
Yes, and so does != > < >= <= all the relational operator.
C11(ISO/IEC 9899:201x) §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.107) The result has type int.

From the standard :
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.
For logical operands (&&, || ) :
6.5.13 Logical AND operator ( or 6.5.14 Logical OR operator )
The && (or ||) operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
You can check the last draft here : http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
Conclusion :
All the equality and relational operator (==, !=, <, >, <=, >=) return 0 for false and 1 for true.
The logical operators (==, ||, !) treat 0 as false and other values as true for their operands. They also return 0 as false and 1 as true.

The comparison (equality and relational) operators (==, !=, <, >, <=, >=) all return 0 for false and 1 for true — and no other values.
The logical operators &&, || and ! are less fussy about their operands; they treat 0 as false and any non-zero value as true. However, they also return only 0 for false and 1 for true.

Can I assume that in C, the "==" operator will always evaluate to 1 if the two values are equal or it can evaluate to other "true" values?
Yes, for a standard compliant compiler, this assumption is correct:
Programming languages — C, §6.5.9 Equality operators (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf):
Each of the operators yields 1 if the specified relation is true and 0
if it is false. The result has type int.

Related

Explanation of shortcuts in C

Can someone explain what exactly is happening in these two statements listed below:
1) int enabled = val == 0; //val is an int
2) int sync = param || (foo->delay == NULL); //param and delay is both int
int enabled = val == 0;
read as
int enabled = (val == 0);
and
(val == 0)
will be either 0 or non zero if val is 0 or not. enabled will then be initialized with that value
Equivalent to:
int enabled;
if(val == 0)
{
enabled = 1;
}
else
{
enabled = 0;
}
now you do that same analysis on the second one
You will set the variable enabled to 1 if val is equal to 0 and 0 otherwise.
sync will be equal to 1 if param is non-zero and in case it is 0 then it will be 1 if foo->delay is NULL else it will be 0.
From standard §6.5.9p3 backing up what I said:
The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.108) 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.
Also in case || there is standard saying the evaluation logic: from §6.5.14
Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares unequal to 0, the second operand is not evaluated.
Also in the same section the rule which dictates what will be the result if param is non-zero.
The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
C only adopted a true boolean type from C++ with C99, though it named it _Bool so it wouldn't conflict with pre-existing code and provided the header <stdbool.h> to make it nicer.
The prior convention that only 0 is considered falsey (a literal zero, which in a pointer-context is a null-pointer), and anything else truthy was not changed. (That's the reverse to how command shells do it by the way.)
All boolean operators and conversion from _Bool use canonical values of 0 and 1.
That should be enough history and details to understand the code.

What is short-circuit evaluation in C?

I'm studying C from A Book on C by Kelley-Pohl, and there's this exercise that I don't understand:
int a = 0, b = 0, x;
x = 0 && (a = b = 777);
printf("%d %d %d\n", a, b, x);
x = 777 || (a = ++b);
printf("%d %d %d\n", a, b, x);
They just say to imagine the output and compare it to the real one. I thought the output would have been
777 777 0
778 778 1
but it is
0 0 0
0 0 1
From the C Standard (6.5.13 Logical AND operator)
3 The && operator shall yield 1 if both of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
and
4 Unlike the bitwise binary & operator, the && operator guarantees
left-to-right evaluation; if the second operand is evaluated, there is
a sequence point between the evaluations of the first and second
operands. If the first operand compares equal to 0, the second
operand is not evaluated.
In this expression statement
x = 0 && (a = b = 777);
the first operand compares equal to 0. So the second operand is not evaluated that is the values of the variables a and b are not changed. So the variable x will be set to 0 according to the paragraph #3 of the section.
From the C Standard (6.5.14 Logical OR operator)
3 The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
and
4 Unlike the bitwise | operator, the || operator guarantees
left-to-right evaluation; if the second operand is evaluated, there is
a sequence point between the evaluations of the first and second
operands. If the first operand compares unequal to 0, the second
operand is not evaluated.
In this expression statement
x = 777 || (a = ++b);
the first operand compares unequal to 0. So the second operand is not evaluated that is the values of the variables a and b are not changed.. So the variable x will be set to 1 according to the paragraph #3 of the section.
If you will change the order of the operands in the expressions like
x = (a = b = 777) && 0;
x = (a = ++b) || 777;
you get the expected by you result.
The && operator uses lazy evaluation. If either side of the && operator is false, then the whole expression is false.
C checks the truth value of the left hand side of the operator, which in your case is 0. Since 0 is false in c, then the right hand side expression of the operation, (a = b = 777), is never evaluated.
The second case is similar, except that || returns true if the left hand side expression returns true. Also remember that in c, anything that is not 0 is considered true.
Hope this helps.
Another trap in this expression is that; the precendence of the operators. Such as &&, || (logical and, logical or) operators have higher precedence to the assignment operator(=).
in this case x=(0&&(a=b=777)) is same as x=0&&(a=b=777), however x=(0&(a=b=777)) is more readable than the previous one.
Logical operators select one of their operands and returns the result accordingly.
They also force their operands to be boolean as true or false.
In this expression "x=0&&(a=b=777)" since the first operand is false the result will be equal to first operand.Second operand is short circuited and will not be executed.So the output will be a=b=0, x=0.
x=777 || (a=++b) in this expression since the first operand is true the result will be equal to the first operand and logical operator will not check the second operand, logical OR operator will bypass the second operand.In this expression since the first operand is true (777 is converted to true) the result will be True means x=1.Since the second operand is skipped "a" and "b" values will remain same as their previous values, in this case 0,0

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);
}

How to determine if logical expressions are equivalent or not

I do not know how to test this using a truth table because I haven't been taught that yet. Can someone explain if the expression !(a < b) the same as !a >= !b ?
Expression (a < b) is logical expression. We can say about it that it is true or it is false. (a < b) is true for example when a = 1 and b = 3. Otherwise, (a < b) is false when a = b or for example, when a = 5 and b = 2.
!(expression) -- is unary logical operator NOT which is true when expression is false, and it is false when expression is true.
So, when you write !(a < b) logically it means NOT (a < b), so it is (a >= b).
In C you can use unary operator !. The result of the logical negation operator ! is 1 if the value of its operand is zero, and 0 if the value of its operand is nonzero. The type of the result is int. The logical negation operator is applicable to any arithmetic type and to pointers.
So, technically, syntax of expression (!a >= !b) is correct, but from logical point of view its nonsense in your case.

What is !0 in C?

I know that in C, for if statements and comparisons FALSE = 0 and anything else equals true.
Hence,
int j = 40
int k = !j
k == 0 // this is true
My question handles the opposite. What does !0 become? 1?
int l = 0
int m = !l
m == ? // what is m?
Boolean/logical operators in C are required to yield either 0 or 1.
From section 6.5.3.3/5 of the ISO C99 standard:
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.
In fact, !!x is a common idiom for forcing a value to be either 0 or 1 (I personally prefer x != 0, though).
Also see Q9.2 from the comp.lang.c FAQ.
§6.5.3.3/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 other logical operators (e.g., &&, ||) always produce either 0 or 1 as well.
Generally, yes, it'll become 1. That said even if that is guaranteed behavior (which I'm not sure of) I'd consider code that relied on that to be pretty awful.
You can assume that it's a true value. I wouldn't assume anything more.
The Bang operator (!) is the logical not operator found commonly in C, C++ and C#, so
!0 == 1
!1 == 0
This is based on the language characteristic of what is interpreted to be either true or false... in more modern languages it would be like this
!false == true
!true == false
See DeMorgan Law concerning truth tables...
!x will be expand to (x==0) so:
if x=0 -> !x take value from (0==0) = TRUE (value 1)
if x!=0 -> !x take value from (x==0) = FALSE (value 0)

Resources