What logical AND operation does with stream output? - c++

I just saw the code and I am unable to understand how the logical and behaves with "cout" here:
int userInput = 9; // Suppose user input is 9.
int remainder = 9 % 2;
(remainder & 1 && std::cout<<"odd" )|| cout<<"even";

std::cout<<"odd" is an expression that will return std::cout (which is why you can do std::cout << a << b << c). When evaluated in boolean context, it simply returns true if the fail bit isn't set. So if the output operation succeeds then it will evaluate as true.
However, the intent of this code isn't to test that value, rather it is a clever (and not very readable)1 way to express this:
if (remainder & 1) {
std::cout << "odd";
} else {
std::cout << "even";
}
It takes advantage of the short-circuiting nature of the && and || operators:
In a && b, if a is false then it evaluates as a (b is not evaluated!) otherwise it evaluates as b.
In a || b, if a is true then it evaluates as a (b is not evaluated!) otherwise it evaluates as b.
So if remainder & 1 evaluates as false (zero in this case) then std::cout << "odd" is not evaluated because the && expression short-circuits, returning false. This is the left operand to the outer || expression, which causes its b (std::cout << "even") to be evaluated, writing "even" to the output.
If remainder & 1 evaluates as true (non-zero in this case) then the right operand for && is evaluated, displaying "odd". Assuming that this operation succeeds, the left operand for the || operation will be true, which causes it to short-circuit and not evaluate the right operand.
1 Experienced programmers are likely to know exactly what is going on here, but as you have found this technique is not the most readable. It's better (IMO) to be straightforward about the intent of code, so I would just use an if conditional -- or, at the very least, use the ternary operator: std::cout << (remainder & 1 ? "odd" : "even").
In other languages (JavaScript comes to mind) (ab)using the short-circuiting operators is a very common technique. I usually don't see them used this way in C++ and I would strongly discourage such use.

The line in question:
(remainder & 1 && std::cout<<"odd" ) || cout<<"even";
Is the same as the following when you take operator precedence and operator overloads into account:
((remainder & 1) && (operator<<(std::cout, "odd").operator bool())) || (operator<<(std::cout, "even").operator bool());
std::cout (more generically, std::basic_ostream) has operator<<() and operator bool() operators defined. The first operator returns a std::basic_ostream& reference, ie a reference to the stream itself (useful for chaining operations together). The second operator returns whether the stream is in a failure state or not.
See the following documentation for more details:
C++ operator precedence
operator overloading
std::basic_ostream::operator<<
std::basic_ios::operator bool

Related

Checking container size in same "if" statement as reading from it

Let's say I have a vector of unknown length.
I want to check if there is a value at vector[3] that is equal to x.
I have to first check if the vector has a length of at least 4.
if(vector.length()>=4)
{
if(vector.at(3) == x)
// Do something
}
My question is: Is it correct to write the same code like this:
if(vector.length()>=4 && vector.at(3) == x)
// Do something
?
Yes, these are equivalent.
The logical AND operator && has what is referred to as short circuit behavior. If the left operand evaluates to false (i.e. 0) then the entire expression is false and the right operand is not evaluated.

Ternary operator with no condition

I found a section of code that shows the following:
int A = 4;
int Z;
Z = (A ? 55 : 3);
Why does the result for Z give 55?
You seem to have a common misconception about the fact that expressions in conditional statements (if, while, ...) and ternary operations must "look like" a condition, so they should contain a relational/equality/logical operator.
It's not like that. Commonly used relational/equality/... operators don't have any particular relationship with conditional statements/expressions; they can live on their own
bool foo = 5 > 4;
std::cout<<foo<<"\n"; // prints 1
and conditional statements/expressions don't care particularly for them
if(5) std::cout << "hello\n"; // prints hello
if/?/while/... just evaluate the expression, check if the result, converted to bool, is true or false, and act accordingly. If the expression doesn't "looks like" a condition is irrelevant, as long as the result can be converted to bool you can use it in a conditional.
Now, in this particular case A evaluates to 4, which is not zero, so when converted to bool is true, hence the ternary expression evaluates to its second expression, so 55.

What's the point of logical operators vs. bitwise operators

Given this statement is a logical operation
((a > 5) && (b > 4))
And this statement is bitwise-operation
((a > 5) & (b > 4))
Above two statements is not equivalent.
Because (a > 5) is an element of {0,1}
So, why do we need logical operators & bitwise-operation?
Edit: thanks for all of the feedback. Regarding the short circuit behaviour of logical operators, I actually do not want this behaviour - I am writing code for a GPU where branches degrade performance: short circuit results in two branches instead of one in the code.
For numerical comparisons in C, in the case where short circuit is not needed, it seems that logical and bitwise have identical behaviour. In my case, bitwise ops are faster than logical.
I apologize for not putting these details in the original posting.
I think no, take this example (0b - means binary):
a = 0b00000010
b = 0b00000100
Now, neither a nor b is 0. But a & b == 0 (due to the way bitwise AND is defined).
However a && b != 0 (because for logical AND result is 0 if at least one operand is 0 - this is not the case with a and b above).
Also there is short circuit evaluation, if in && left operand is 0, the right one will not be evaluated because result is certainly 0 (e.g., as already mentioned 0 && x == 0 no matter value of x).
The logical operators convert their operands to bool before combining them and the result of a logical operator is also bool all the time. The bitwise operators do not do this (however in case of operands that are bool anyway this doesn't make a difference between the two kind of operators).
Logical operators can be used on a lot of operand types that can be converted to bool while bitwise operators work only on a few types in specific cases and the output of bitwise operators are typed (not always bool).
the logical operators are shortcut. For example in case of && this means: if the first operand is false, then the second operand isn't even evaluated because the whole expression (false && something) is already false regardless of the value of the second operand.
The logical shortcut operators are often exploited in cases like the following:
// If mypointer is NULL, then mypointer->is_whatever()
// isn't evaluated so it doesn't cause a NULL pointer crash.
if (mypointer && mypointer->is_whatever()) {
// do my thing
}
Logical operators are to compare multiple values true-itiveness.
For example, you use the && operator to see if two values are both true.
Bit-wise operators are for isolating and modifying bits in a value.
For example, in order to turn off all the bits in an 8-bit value except for one, you would do this:
val & 00100000
In the above example, the 6th (1-based) or 5th (0-based) bit is kept as it was, and the other bits are turned off.
Both types of operators are similar in that they both either yield 0 or 1.
For example, take these:
1 || 0
The above would yield 1 because either of the values is equal to 1. However, if we switch the operator to &&, it would yield 0.
Out of all the operators you try, they will all either give 1 or 0, true or false. That is because there is no between: there is no such thing as an expression evaluating to "sort-of true" or "maybe false".
And I think the reason why a bit-wise operator always "yields" 1 or 0 is pretty self explanatory: bit-wise; a bit is either 1 or 0.
Not all expressions used as booleans evaluate to either 0 or 1; while 0 is treated as false, anything other than 0 is treated as true. So, for example, 1 && 2 would be true, but 1 & 2 would not, even though both 1 and 2 would be considered true.
Also, as others have pointed out, the logical operators will not evaluate the second expression if the first is enough to determine the overall value ('short-circuiting'), which obviously cannot be done with the bitwise version (well, not as often; 0 & ? will be 0 no matter what ? is, and thus ? wouldn't need to be evaluated to get the final value, but & doesn't work that way).

precedence of () is not greater than &&

In the following code,
int main() {
int a =1, b = 2, c = 3;
if(((a++) == 5) && ((b++) == 5) && ((c++) == 5)) {
cout<<"inside if"<< endl; // prints !!!Hello World!!!
}
cout<<a<<b<<c<<endl;
return 0;
}
all increment operation should be done before doing logical operation. But execution skips increment b and c. Why logical && precede over ()? By the way, result of this code is 223.
Because of short circuiting: when the left hand side of && is false, the right-hand side is not evaluated. The precedence, on the other hand, is the way you think it should be (and, as AnT says, it's unrelated to the behavior you're seeing): () has precedence over &&.
(Similarly, when the left hand side of || is true, the right-hand side is not evaluated.)
all increment operation should be done before doing logical operation
This is simply not true. There's no reason why increment operation should be done before doing logical operation and () does not change that in any way. As it has been stated many times before, operator precedence does not have anything to do with order of evaluation. These are two completely unrelated concepts.
At the top level, your expression has the following structure
<term1> && <term2> && <term3> && ... && <termN>
Such expressions are always evaluated in strictly sequenced left-to-right order from <term1> to <termN> (with possibly short-circuited evaluation). It is completely irrelevant what you have inside those terms: nothing inside <term2> will ever be evaluated before <term1>.

Operator |= for a boolean in C++

I stumbled upon the following construction in C++:
bool result = false;
for(int i = 0; i<n; i++){
result |= TryAndDoSomething(i);
}
I supposed that this |= was a shortcut for the OR operator, and that result would equal true in the end if at least one of these calls to TryAndDoSomething had returned true.
But now I am wondering if more than one call can actually return true. Indeed if we extend the operation as:
result = result || TryAndDoSomething(i);
Then the method will be called only if return evaluated to false, that is, if no other call before returned true. Thus after one call returning true, no other call will be done.
Is this the correct interpretation?
It's bitwise OR assignment, not short-circuited OR evaluation.
It is equivalent to:
result = result | TryAndDoSomething(i);
Not:
result = result || TryAndDoSomething(i);
On booleans, | yields the same result as ||, but doesn't short-circuit. The right operand of |= is always evaluated.
The only difference in this context between x |= f() (bitwise OR) and x = x || f() (logical OR) is that the latter is short-circuiting. In the former, f() will be executed n times—unless of course f() throws an exception, but that’s another story.
In the || version, f() will no longer be called once x becomes true. C++ does not have a ||= operator, but it is important to understand that |= and ||= (if it existed) would have different semantics because of this. |= is not just a replacement for the missing ||=.
As a side note, provided you are using bool, the bitwise operation is safe, because the standard specifies that true and false convert to the integers 1 and 0, respectively. So the only difference in this case is eager versus lazy evaluation.
result |= Try() is short for result = result | Try();. The || operator you seem to understand, but the | operator is quite different. It's name is bitwise or (as opposed to logical or). It has the same affect as if it performed a=a||b on each bit of the operands, and doesnt have the quick-bailout thing that logical and/or have. (It's also crazy fast; as fast or faster than addition). The other bitwise operations are & (bitwise and: a=a&&b on each bit), and ^ (bitwise xor: a=(a!=b) on each bit).