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);
}
Related
I don't understand why it prints 1 at the end.
#include <stdio.h>
int main(){
printf("%d\n", -2&&2);
return 0;
}
&& is a Boolean operator, not an integer operator. In C any non-zero value is interpreted as true when applied to a Boolean operation, while zero is the only integer value regarded as false when applied to a Boolean operation.
So:
(<non-zero> && <non-zero>) == true
then conversely when a true result is treated as an integer (as the %d format specifier dictates in this case), true is represented by 1, while false is zero. So in this case true becomes 1.
If you want to print a Boolean result, then:
printf( "%s\n", (-2 && 2) == 0 ? "false" : "true" ) ;
Strictly the expression:
-2 && 2
is equivalent to:
(-2 != 0) && (2 != 0)
Which has strict type agreement since != has a Boolean result from integer operands, and so && is presented with Boolean operands only with no implicit conversion.
Because -2&&2 is evaluated to true = 1 (when you AND two numbers together you will get true unless one or both of the numbers is 0).
Try changing -2&&2 to true && false; it will print 0.
The expression -2&&2 resumes to 1 or true (true is always != 0, while false == 0) based on the boolean arithmetic opration.
And here is how it resumes to 1:
&& represents the logical AND, not bitwise AND, which is &, in C. So you are logical ANDing the values of -2 and 2.
Let´s consider the following sentence as one of the statements for the Logical AND (&&)-operation:
If both the operands are non-zero, then the condition becomes true.
-2 is non-zero, equals 1.
2is also non-zero, equals 1.
So the result is also 1 (1AND 1 = 1) or true represents 1.
The && operator is for logical and, not bitwise and.
The expression in your program evaluates as
printf("%d\n", (-2 != 0) && (2 != 0));
Which is 1 because boolean expressions have value 0 for false and 1 for true in C.
Conversely, if you had written -2 & 2, you program would have implementation defined behavior, depending on the representation of negative integers used for the target system. On modern systems with two's complement representation, this bitwise and expression evaluates to 2. Same value for sign-magnitude representation, but on rare systems with ones' complement representation, the value would be 0.
Why C has both || and | operators? As far I know, | operator can replace || in conditions because it will return true (nonzero) value when at least one of operands is nonzero.
I ask just out of my curiosity. I know I should use || for logical expressions.
Example
#include <stdio.h>
int main(void) {
int to_compare = 5;
/* Try with bitwise or */
if ((5 > to_compare) | (to_compare == 6)) {
printf("‘to_compare’ is less than or equal to 5 or equal to 6.\n");
}
/* Try with logical or */
if ((5 > to_compare) || (to_compare == 6)) {
printf("‘to_compare’ is less than or equal to 5 or equal to 6.\n");
}
return 0;
}
|| and | are very different beasts.
Aside from || having the short-circuting property (the right operand is only evaluted if the left one evaluates to 0), it's also a sequencing point.
The value of the expression can also be different: 1 || 2 for example is 1 whereas 1 | 2 is 3.
(Note that && and & have a more pernicious difference, for example 1 && 2 is 1 whereas 1 & 2 is 0.)
In addition to the fact that the || operator is short-circuiting, the result of the || operator is always either 0 or 1 based on its truth, whereas the result of the bitwise or | operator will be a combination of bits that were set in the operands, which is not necessarily 1 (i.e. 0x0A | 0xB0 = 0xBA, whereas 0x0A || 0xB0 = 1.
§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.
§6.5.12 Bitwise inclusive OR operator
The result of the | operator is the bitwise inclusive OR of the operands (that is, each bit in
the result is set if and only if at least one of the corresponding bits in the converted
operands is set).
In BCPL and B -- C ancestors --, there is only | and &. But their interpretation is dependent on the context: in control structures like if, they behaved like the C logical operators, in other contexts, they behaved like the C binary operators. That was deemed too difficult to use and explain and thus additional operators where introduced so that the operator used indicated clearly if the operation was logical and short-circuiting, or binary and not short-circuiting. And that also explains the inconvenient relative priorities with comparison operators.
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.
I was under the impression that in the C language, the logical OR operator || is a short circuit operator that doesn't evaluate the rhs if the lhs is false. I've run into a problem when comparing OR'ed values. Can someone explain to me why the following code (on gcc 5.3) evaluates to true? I'm getting the same behavior in clang.
#include <stdio.h>
int main() {
int attr = 2;
if( ((attr & 2) != 2) || ((attr & 4) != 4) ) {
printf("No short circuit?\n");
};
printf("%i %i\n",attr,(attr & 2));
};
output:
No short circuit?
2 2
((attr & 2) != 2) || ((attr & 4) != 4) evaluates to true because
attr & 4 == 0 and (attr & 4) != 4 is 1 because attr & 4 is not equal to 4. (N1570 6.5.9 Equality operators)
Because at least one of the operand is not zero, the expression evaluates to 1. (N1570 6.5.14 Logical OR operator)
The if statement excutes the first substatement when the controlling expression is not zero (N1570 6.8.4.1 The if statement), and you will call it "the expression evaluated to true".
Logical OR operator won't evaluate rhs if the lhs is true because the value will be true in both case the rhs is true or false.
Logical AND operator won't evaluate rhs if the lhs is false because the value will be false in both case the rhs is true or false.
Quote from N1570:
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.
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.
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.
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.
Code that you had:
((attr & 2) != 2) || ((attr & 4) != 4) )
What happens:
(attr & 2) evaluates to 2. (0010 AND 0010 = 0010 which is 2)
(2 != 2) evaluates to 0, or false.
Now the right side of the OR is evaluated (If the left side was true, then the right side would not be executed/evaluated, i.e. "Short circuit". But in this example it is false, so the right side is evaluated).
(attr & 4) is the bitwise and operation, e.g. 0010 & 0100. It evaluates to 0000, or 0.
(0 != 4) evaluates to 1, or true, so the body of the if statement executes.
The rest of the program (the last statement) then executes and the program terminates.
Remember:
& is bit-wise AND.
&& is Boolean AND.
| is bit-wise OR.
|| is Boolean OR.
Here's two ways you can get the short circuiting behavior in C:
unsigned int bitwise_logical_or(unsigned int p, unsigned int q) {
return (p | (q & ((p != 0) - 1)));
}
unsigned int numerical_logical_or(unsigned int p, unsigned int q) {
return p + (p == 0) * q;
}
As mentioned in other answers, the || operator returns true (0x01) or false (0x00).
bitwise_logical_or works as follows:
If bitwise or is performed on integers p and q, it will work only so long as p is zero. If p is not zero, bitwise or will intermingle p and q in an unpredictable way. If q could be set to zero if p is greater than zero we’ll get the result we want. Therefore, when p is non-zero, we’d like to perform a bitwise and between q and zero. The trick is that simply testing p == 0 will return (in 8 bit) 0x00 or 0x01. We need it to return 0xff or 0x00 appropriately. We accomplish this by checking p != 0, this will return 0x01 when p > 0 and 0x00 when p == 0. Subtract 1, and in the case that p > 0, you get 0x00 (false). When p == 0, you already have 0x00 (all zeros), there’s no where to go, so the integer wraps around (underflows) and you get 0xff (all ones).
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.