In C is & shorthand for logical and(&&)? - c

Sometimes I want to do something like this (with i and j being ints).
(if i==4 && j==9)
{
...
}
Where it'll go through the brackets if i equals 4 and j equals 9. I've been using a single ampersand (&) instead of a double one and my code's been compiling and running.
Is it doing the same thing as a double ampersand &&, and if not what has it been doing?
Edit: Oh and I've been doing the same thing with or, using '|' instead of '||'

Presumably you mean if (i==4 && j==9).
Under the circumstances, changing this from && to & shouldn't change much. The big thing that'll change is that with &&, the j==9 would only be evaluated if the i==4 part was true, but with &, they'll both be evaluated regardless.
When you have something like if (x != NULL && x->whatever ...) you want to ensure that the second part (that dereferences x) is only evaluated if x is not a null pointer. In your case, however, comparing what appear to be ints is unlikely to produce any problems.
It's also possible to run into a problem when you're dealing with something that may produce a value other than 1 to signal true. Again, it's not a problem here because == will always produce either 0 or 1. If (for example) you were using isalpha, islower, etc., from <ctype.h>, they're only required to produce 0 or non-zero values. If you combined those with a &, you'd get a bit-wise or which could produce 0 for two non-zero inputs (e.g., 1 & 2 == 0, but 1 && 2 == 1).
When you use bitwise and on the results from ==, you're going to get 0 & 0 or 0 & 1 or 1 & 0 or 1 & 1. 1 & 1 will yield 1 (true). All the others will yield 0 (false) --- just like && would have.

It's performing a bitwise AND.
What it's doing is the expression i == 4 is equivalent to 1 if i is 4 and the same for the RHS (with j and 9, obviously). The & operator returns the number where both operands have that bit on.
It works the same as && because 00000001 & 00000001 (slimmed down to a byte for example) is the same. If one is 0 (the condition was false), then the & won't see two bits turned on for both operands, and 00000000 is 0, which is falsey.
However, do not simply use & because it's one character shorter or similar. Use it because it expresses what you want to achieve. If it's a logical AND you want, use &&.
The same thing applies to |, except instead of a resulting bit if each operand has it turned on, it turns it on if either operand has that bit turned on.

A single ampersand does a bitwise AND. Every bit of the result is set only if both operands have a 1 in that position.
Since comparisons in C return 1 for true and 0 for false, & will give the same results as && as long as both operands are comparisons. But for arbitrary values, it will return seemingly random results. 1 && 2 is true, but 1 & 2 is false because the binary representations of 1 and 2 have no bits in common.

A single ampersand is called a bitwise and. It is a binary operator that 'ands' two numbers bit by bit.
For instance, if you have two binary numbers, 01100010 and 00011111, your bitwise and will result in 00000010
i==4 returns 1 (true), as does j==9. So, i==4 & j==9 is really just 1 & 1, which evaluates to 1 (true).
Try these examples to see the difference
1) int k = 4 & 6; vs int k = 4 && 6;
2) if(i==4 && 2) vs if(i==4 & 2)

Related

Why does C have both logical and bitwise ‘or’ operators?

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.

Using Logical AND 1 when setting a variable in C

While looking through some code today, I came across an interesting(unecessary?) method for setting a variable: Adding a logical AND to the value.
LED_GRN = (ivLEDGrnSequence & ivLEDSlot) && 1;
I looked around a bit more for some of these occurrences and found them throughout the code, but in different forms:
As an argument for a function:
isoAgCmdHideShow(iObjectID,( (ecu.l & sVar->mask) && 1), (uint8_t *)TxMsg.buf);
In a conditional:
if( (usbQueue.selection & USB_SELECTION_CAN_1) && 1 ) {return TRUE;}
Does this extra logical AND actually change anything about the code, or is it just superfluous? I tried searching for this online, but the closest I found to an answer is Short-Circuit Evaluation which doesn't seem to apply in these situations because short-circuiting a 1 is useless.
In short, what does Logical AND 1 do for variable declaration?
This appears to be a trick to force any non-zero number to 1, while keeping zeros - alongside a more common !!(expr) idiomatic construct.
The idea is to set LED_GRN to 1 or 0 based on the value of ivLEDGrnSequence & ivLEDSlot.
Other ways to do the same thing are as follows:
LED_GRN = !!(ivLEDGrnSequence & ivLEDSlot);
LED_GRN = (ivLEDGrnSequence & ivLEDSlot) != 0;
Doing x && 1 produces either 1 or 0, regardless of what non-zero value the left operand evaluates to.
From the C standard:
§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.
It's converting the result of the bitwise AND to either 0 or 1. The result of the bitwise AND can be 0 or any non-zero number. But after the logical AND, the result can only be 0 or 1.
So the first two examples may be useful. The third example with the if statement is definitely not useful, since if converts the expression to a boolean.
The result of logical operation (in this case &&) is either 0 or 1. The result of arithmetic or bitwise operation (& in this case) is 0 or non-0. If we want to convert any non-0 to 1 we perform a logical operation on it. The more common and idiomatic way to accomplish this is the double negation:
LED_GRN = !!(ivLEDGrnSequence & ivLEDSlot);

Difference between & and && in C?

What is the difference between & and && in C?
My teacher gave me this example:
int a = 8;
int b = 4;
printf("a & b = %d\n", a & b);
printf("a && b = %d\n", a && b);
Output:
a & b = 0;
a && b = 1;
I'm not sure why this would return true in one scenario and false in another.
& is bitwise and and && is logical and.
The expression x && y will return 1 if both x and y is non-zero, and 0 otherwise. Note that if x is zero, then y will not be evaluated at all. This will matter if y is an expression with side effects. This behviour is called short circuiting.
The expression x & y will perform a bitwise operation on each individual bit in x and y. So if x is 1010 in binary and y is 1100 then x & y will evaluate to 1000. Note that the return value of x & y should NOT be interpreted as a Boolean value, even if it's possible. In early C, the operator && did not exist, and because of that & was used for this purpose.
One way to explain it is that you could imagine that & is the same thing as applying && on each individual bit in the operands.
Also note that & has lower precedence than &&, even though intuition says that it should be the other way around. This also goes for comparison operators, like <, <=, ==, !=, >=, >. This goes back to the time when C did not have the operators && and || and the bitwise versions was used instead. At this time, it made sense, but when the logical operators were added, it did not anymore. Kernighan and Ritchie admitted that it would have made more sense, but they did not fix it because this would break existing code.
I'm not sure why this would return true in one scenario and false in another.
The return value from x & y should not be treated as a Boolean value at all. However, it can (depending on how the code is written) be treated as a Boolean array. If you have two integers, flags1 and flags2 then the result of flags1 & flags2 will denote which flags that are toggled in both flags1 and flags2.
The & operator performs a bit-wise and operation on its integer operands, producing an integer result. Thus (8 & 4) is (0b00001000 bitand 0b00000100) (using a binary notation that does not exist in standard C, for clarity), which results in 0b00000000 or 0.
The && operator performs a logical and operation on its boolean operands, producing a boolean result. Thus (8 && 4) is equivalent to ((8 != 0) and (4 != 0)), or (true and true), which results in true.
&& (logical and operator) - The left and right operands are boolean expressions. If both the operands are non-zero, then the condition becomes true.
>
& (bitwise and operator) - The left and right operands are integral types. Binary AND Operator copies a bit to the result if it exists in both operands.
In your teacher's example a && b, the left operand 4 and the right operand 8 are both non-zero. So the condition will become true.
In your teacher's other example a & b, the left operand 4 or 0100 and the right operand 8 or 01000 copies no bits to the result. This is because there are no common set bits in either operand.
& is bitwise operator and, && is logical for example if you use two number and you want to use bitwise operator you can write & .
if you want to use to phrase and you want to treat them logically you can use && .

Bitwise Operation !x and x==0

I just want to ask a question.
Is !x the same as x==0 ?
I'm using these to test a condition (an interrupt), in this case x is only a single bit.
Sample of the code where I'm using it:
if(PIR1bits.SSPIF & !SSPCON2bits.ACKSTAT)
{
// some operation
}
Why not do a simple table ?
x !x x==0
0 1 1
1 0 0
So the evaluation of if(!x) or if(x==0) should be the same in your case.
edit
Just to precise that in your code the & operator refers to the bitwise AND operator so your condition can only be true if PIR1bits.SSPIF=1 and SSPCON2bits.ACKSTAT=0
As noted by coincoin, you probably want your code to read
if(PIR1bits.SSPIF && !SSPCON2bits.ACKSTAT) {...}
so that you are using a logical 'and' rather than a bitwise 'and'. Bitwise operators (&, |, ^, ~) are usually used to implement masks where you want to test, set, or clear bits within a byte or word. If you use them in if statements, you risk weird behaviour that can be difficult to debug.
You can do things like
if (i & 0x80) {...}
to test if bit 15 is set, or something like
uint16_t a, b;
a = b & 0xfff0;
to clear the lower nibble of b and assign this to a.

How to toggle an int / _Bool in C

Suppose we have an int and want to toggle it between 0 and 1 in a boolean fashion. I thought of the following possibilities:
int value = 0; // May as well be 1
value = value == 0 ? 1 : 0;
value = (value + 1) % 2;
value = !value; // I was curious if that would do...
The third one seems to work. Why? Who decides that !0 is 1?
Is something wrong with any of these?
Are there other possibilities? e.g. bitwise operators?
Which offers the best performance?
Would all that be identical with _Bool (or bool from stdbool.h)? If not, what are the differences?
EDIT: Many great answers with lots of valuable information, thanks! Unfortunately, I can only accept one.
value = !value; expresses what you want to do directly, and it does exactly what you want to do by definition.
Use that expression.
From C99 6.5.3.3/5 "Unary arithmetic operators":
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).
The third one seems to work. Why? Who decides that !0 is 1?
C Standard guarantees that !0 is 1.
Are there other possibilities? e.g. bitwise operators?
Yes, you can use the exclusive OR operator:
value ^= 1;
By the way I prefer this to value = !value; as relational and equality operators can result to branching and bitwise operators usually do not.
value = 1 - value; // toggle from 0 to 1 ... or 1 to 0
// when you know initial value is either 0 or 1
the language was designed that way.
Use the 3rd one, the others are right but unnecessarly complicated and therefore hiding the intent.
value = (value ^ 1) & 1;
They're all the same after optimisation.
_Bool would have the same results. The only thing different with _Bool is that values are coerced to be either 1 or 0. Meaning that bool x = 55; will have the value x == 1
EDIT: Corrected the formula in 3 because of my brainfart. I let the comments so that people can see my blooper.
value = !value seems the most reasonable one, but you can also use value = 1 - value or value ^= 1. But the last two would both break if value is not 0 or 1. The first one would still work.
There can be noticeable performance issues with the alternatives depending on the architecture:
!a might need in some architectures comparison and branching, which can be expensive depending on the pattern of 'a'
on some architectures there is conditional move (which is branchless), but
which may require still 3 instructions to complete (with dependencies)
1-a most likely needs two instructions in many architectures
counter example: ARM has reverse subtraction RSB %r0, %r0, #1
1^a can be implemented in many architecture with a single instruction
a=(a+1) % 2 will be most likely optimized to a=(a+1)&1, which requires 2 instructions
But anyway the first rule of optimization is that don't optimize a non working code.
To replace !a with a^1, one has to be 100% certain that it produces always the expected value.
Your expression value = value == 0 ? 1 : 0; will work exactly like value = !value;. You can use any of the two.
!0 is always 1 and also !(any non zero value) is 0
Use bitwise NOT operator
var = ~var;

Resources