This question already has an answer here:
The output of cout << 1 && 0;
(1 answer)
Closed 7 months ago.
Consider:
int i = 56, j = 0;
int n = i&&j;
cout << i&&j;
cout << endl << n;
whose output would be:
56
0
I imagine it's either because of operator precedence or logical short circuit, but I can't seem to figure out which, or the reason.
The expression cout << i&&j is equivalent to (cout << i) && j. Both operands are evaluated and converted to bool. The statement as a whole has no effect, but the evaluation of the subexpression cout << i has the usual side effects, of course, namely writing something to the standard output.
The && operator is indeed short-circuited and j is only evaluated if cout << i evaluates as true. This condition is equivalent to cout.good(), which is usually the case (unless you somehow managed to close your standard output).
As you expected, the << operator comes takes precedence over &&.
Thus, cout << i&&j first outputs i, then compares the returned stream to j (both are true, so the returned value is true, but this value is discarded).
See here for the full list of operator precedence.
Related
This question already has an answer here:
The output of cout << 1 && 0;
(1 answer)
Closed 4 years ago.
#include <iostream>
using namespace std;
int main()
{
int a = 8;
cout << "ANDing integer 'a' with 'true' :" << a && true;
return 0;
}
Why does this program output 8 and not 1 (for true)?
If you look at operator precedence, you will find that the left-shift operator << has a higher precedence than the logical AND operator &&.
As such, it is evaluated as:
(cout << "ANDing integer 'a' with 'true' :" << a) && true;
which prints 8.
The logical AND operator, &&, works with expressions.
The first expression is evaluated.
If the first expression is false, no more evaluations.
Otherwise the second expression is evaluated.
Next, the result of the two Boolean expressions is returned.
So, the first expression is evaluated:
cout << "ANDing integer 'a' with 'true' :" << a
A side effect of the evaluation is the following output to the console:
ANDing integer 'a' with 'true' :8
Your output is generated because it is a side-effect of evaluating the first expression.
In the expression 8 && true 8 is evaluated first (and in this turn also streamed). Than true is evaluated and the operator returns true after that. But than the 8 is already in the stream. If you put (8 && true) instead, the parentheses are evaluated first and the result is guarantreed to be 1, which then is streamed.
This behavior is called Operator Precedence - which describes the order in which the operators are executed (in your case && and <<).
The logical AND operator && works with expressions. If both are true returns true and false if otherwise.
cout << "ANDing integer 'a' with 'true' :" << a && true;
is being evaluated as:
(cout << "ANDing integer 'a' with 'true' :" << a) && true;
due to operator precedence (<< having higher precedence than AND &&)
giving you the print of: 8
if we do the following change: (a && true);
it will give you the print of: 1
This question already has answers here:
Cannot understand for loop with two variables [duplicate]
(3 answers)
Closed 6 years ago.
This compiles and runs, but produces garbage values for "a". Why doesn't "a" increment like "b"? Why is it producing garbage?
for(a,b=0; a,b != 55; a,b++)
{
//outputs garbage
std::cout << "a = " << a << std::endl;
//outputs expected results
std::cout << "b = " << b << std::endl;
}
The comma operator says execute the expression on the left then execute the expression on the right:
a, b=0
first executes a which does nothing, then it executes b=0 which assigns zero to b.
Why does the comma operator exist? The comma operator can be useful when the expressions have side effects.
It also serves a sequence point which tell the compiler "everything on the left must be complete before anything on the right happens. This constrains the optimizations allowed by the compiler, so for example a += 1, b = a + c[a] will always add one to a before using it as an index. Something like b = ++a + c[a] is undefined because the compiler can increment a before or after it uses it as an index.
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Closed 6 years ago.
I want to write several lines to a file. Each line has an index (running index).
My code is:
ofstream outputFile;
int index = 0;
outputFile << ++index << ") FirstLine" <<endl
<< ++index << ") SecondLine" <<endl
...
<< ++index << ") LastLine" <<endl;
Problem is that I get no running index. That is, all lines has the same index (which is the total lines number). So my questions are firstly, how does ofstream work (meaning why do I get the described result). Secondly, what should I do to get it work?
Firstly, how does ofstream work (meaning why do I get the described result)?
According to the C++ standard (section 1.9, clause 15):
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.
If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, and they are not potentially concurrent, the behavior is undefined.
Applied to your case:
The evaluation of the ++index statements (which are operands to the << operator) is unsequenced.
++index modifies the value of index, and therefore has a side effect on a scalar object.
As such, the behavior is undefined.
Secondly, what should I do to get it work?
One simple option would be to split the single large output expression into multiple lines, such that each ++index statement is on a separate line.
Alternatively, you could both solve the problem and reduce repetition by using a loop.
For example:
#include <array>
#include <iostream>
#include <string>
int main () {
static const std::array<std::string, 3> lines = {
"First line",
"Second line",
"Last line",
};
for (int i = 0; i < lines.size(); ++i) {
std::cout << i + 1 << ") " << lines[i] << std::endl;
}
}
Save this as example.cc, and compile using:
clang++ -std=c++14 example.cc -o example
Then run the example:
$ ./example
1) First line
2) Second line
3) Last line
Note that this prints to standard output to simplify the example, but std::cout can be easily replaced with an instance of std::ofstream depending on your use case.
From this page, I got to know that operator precedence of Bitwise AND is higher than Logical OR.
However, the following program gives an unexpected output.
#include<iostream>
using namespace std;
int main()
{
int a = 1;
int b = 2;
int c = 4;
if ( a++ || b++ & c++)
{
cout <<a <<" " << b <<" " << c <<" " <<endl;
}
return 0;
}
The output is
2 2 4
This means that logical OR works first. Does this mean that the operator precedence rule is violated here?
Precedence just means that the expression is written as below
( (a++ || (b++ & c++)))
Once you do that, short circuiting means that just the first expression is evaluated.
This is why a = 2 but b and c are unchanged.
codepad
this link can help you :
http://en.cppreference.com/w/cpp/language/operator_precedence
precedence
10 & Bitwise AND
11 ^ Bitwise XOR (exclusive or)
12 | Bitwise OR (inclusive or)
13 && Logical AND
14 || Logical OR
this means that '&' is evaluated before '||'.
It's perfectly fine to learn about the precedence of these operators, just out of curiosity. In real life, this code without parentheses to make the intent absolutely clear is just unacceptable.
If the left side of an || has a non-zero value, then the right side isn't evaluated at all. It's guaranteed to be not evaluated.
During work over a simple project I have found situation that I don't fully understand. Consider following code:
#include <iostream>
using namespace std;
bool test(int k)
{
cout << "start " << k << endl;
bool result; // it is important that result's value is opposite to initial value of recheck in main()
result = false;
return result;
}
int main()
{
bool recheck;
recheck = true;
for (int i = 2; i > -1; i--)
{
recheck = (recheck || test(i)); // (1)
cout << i << " ???" <<endl;
}
cout << "----------------------------" << endl;
cout << endl;
recheck = true;
for (int i = 2; i > -1; i--)
{
recheck = (test(i) || recheck); //different order that in (1)
cout << i << "???" <<endl;
}
return 0;
}
It returns completely different results from for loops:
2 ???
1 ???
0 ???
----------------------------
start 2
2???
start 1
1???
start 0
0???
It seems that it first one test(int k) is not even invoked. I suspect it has something to do with || operator. Could anybody explain such a behavior?
The built-in || short-circuits: if the left operand is true, the right operand is not evaluated (it doesn't matter what the value of the right operand is, because the value of the || expression is guaranteed to be true in this case).
For completeness, but not particularly relevant to the question: In c++, the || operator is overloadable, just as many other operators are. If an overload is used, short circuiting does not take place.
The boolean operators || and && will short-circuit when one of the operands - evaluating from left-to-right - can determine the result of the expression, without reference to the remaining operands.
In the case of ||, this means that if the first operand is true, the remaining operands aren't evaluated, because the result of the entire expression will always be true.
In the first loop, the variable recheck - that is local to main - is always true, and so the function call test never needs to be evaluated: it is skipped, and you see no output.
In the second loop, the test function call is evaluated first, and it's result can only be determined after calling the function, so the function is called on each iteration, and you see the output.
Your comment says:
it is important that result's value is opposite to initial value of recheck in main()
Your test() function currently can't see the value of recheck, which is local to main().
Assuming your comment reflects your intent, you need to pass recheck as a parameter to test(); you can then use the unary ! operator, something like:
result = ! recheck;
And of course you need to fix the logic in main() so that test() is called when you need it to be.
Your requirements aren't clear enough for me to comment further.
Others have addressed the specific issue that you have raised. Just a note to say that beware of using multiple question marks in a row. Trigraph sequences start with two '??' characters and the third character after two question marks is interpreted differently.