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";
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:
a && b
, if a
is false then it evaluates as a
(b
is not evaluated!) otherwise it evaluates as b
.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: