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.
Related
This question already has answers here:
Why does it make a difference if left and right shift are used together in one expression or not?
(3 answers)
Unexepected behavior from multiple bitwise shifts on the same line [duplicate]
(1 answer)
Why does combining two shifts of a uint8_t produce a different result?
(2 answers)
Closed last year.
I am doing the following bitwise shift in Microsoft C++:
uint8_t arr[3] = {255, 255, 255};
uint8_t value = (arr[1] << 4) >> 4;
The result of these operations confused me quite a bit:
value = 255
However, if I do the bitwise shift separately:
value = (arr[i] << 4);
value = value >> 4;
the answer is different and makes much sense:
value = 15
Can someone explain to me why this happens? I am familiar with the concepts of bitwise shift, or so I believed...
Thanks in advance!
(P.S.: It seems g++ will have the same behavior. I am probably missing some important concepts with bitwise shift. Any help is greatly appreciated!)
In this expression with shift operators
(arr[1] << 4) >> 4;
there is used the integral promotions. That is the operand arr[1] is promoted to an object of the type int and such an object can store the result of the expression arr[i] << 4.
From the C++ 14 Standard (5.8 Shift operators, p.#1)
...The operands shall be of integral or unscoped enumeration type and
integral promotions are performed. The type of the result is that of
the promoted left operand. The behavior is undefined if the right
operand is negative, or greater than or equal to the length in bits of
the promoted left operand.
Here is a demonstration program
#include <iostream>
#include <iomanip>
#include <type_traits>
#include <cstdint>
int main()
{
uint8_t x = 255;
std::cout << "std::is_same_v<decltype( x << 4 ), int> is "
<< std::boolalpha
<< std::is_same_v<decltype( x << 4 ), int> << '\n';
std::cout << "x << 4 = " << ( x << 4 ) << '\n';
}
The program output is
std::is_same_v<decltype( x << 4 ), int> is true
x << 4 = 4080
As for this code snippet
value = (arr[i] << 4);
value = value >> 4;
then in the first assignment statement the result of the shift operation is truncated.
Expression (arr[1] << 4) will implicitly promote the value of arr[1] to type unsigned int before applying the shift operation, such that the "intermediate" result will not "loose" any bits (cf, for example, the explanation in implicit conversions).
However, when you write value = (arr[i] << 4);, then this "intermediate" result will be converted back to uint_8, and in this step bits get cut off.
See the difference when you write uint8_t value = ((uint8_t)(arr[1] << 4)) >> 4;
I was referring to the question ""IF" argument evaluation order?" for understanding the evaluation order for "if" statement in c++.
Here is the code where the conditions in if statements are evaluated in a wrong order.
#include <iostream>
using namespace std;
int main()
{
int t = 0;
if((1 / t) == 1 && t != 0)
{
cout << "0" << endl;
}
cout << "1" << endl;
return 0;
}
The result is 1 instead of floating point exception.
Division-by-zero is undefined behavior. Anything can happen.
[expr.mul]/4
If the second operand of / or % is zero the behavior is undefined.
divide by zero doesn't guarantee that every time program will throw you a runtime error. this is why dividing by zero is an undefined behaviour.
as C standard states;
The result of the / operator is the quotient from the division of the first operand by the second; the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behaviour is undefined.
as for C++ (03-5.6.4);
The binary / operator yields the quotient, and the binary % operator yields the remainder from the division
of the first expression by the second. If the second operand of / or % is zero the behavior is undefined; otherwise
(a/b)*b + a%b is equal to a. If both operands are nonnegative then the remainder is nonnegative;
if not, the sign of the remainder is implementation-defined
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 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.
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.