According to precedence rules <, >, <=, >=
has precedence over !=, ==
I am so confused that how the following statement will be executed
int a=3, b=3;
cout<< (a != b || a <= b);
I know short circuit evaluation and according to precedence rules I guess that compiler will execute a <= b
first as it has precedence over !=
but it is not doing so.
I did little experiment with above statement by changing a <= b--
and changing order of above conditions and it seems that <=
and !=
have same precedence as compiler execute whichever occurred first. Or I am missing something?
CodePudding user response:
Precedence is not order of evaluation.
Precedence is about where to put parentheses. a != b || a <= b
is parsed as: (a != b) || (a <= b)
. It's not parsed as like for example: a != (b || (a <= b))
or any other combination of (
)
.
After we know where parentheses are, then we can evaluate the expression. The order of evaluation is: (a != b)
first. Then ||
is evaluated. Then, optionally, a <= b
is evaluated.
CodePudding user response:
Precedence of operators is only relevant to how expressions are bound, not to how they're executed. Execution order is dependent on the "happens-before" relationship and otherwise subject to arbitrary reordering by the compiler.
Relative precedence of two operators also only matters if they are directly adjacent. In a == b <= c
, you get a == (b <= c)
, not (a == b) <= c
. In a == b || c <= d
, the adjacent pairs are ==
and ||
and ||
and <=
. In both cases the comparison operators bind more strongly, so you get (a == b) || (c <= d)
, making the relative precedence of ==
and <=
irrelevant. If you have a == b c <= d
instead, you first get a == (b c) <= d
, and now you need to compare ==
and <=
again, getting you a == ((b c) <= d)
.
As for order of evaluation, ||
has a rule that its left side is sequenced before its right side (assuming it's not overloaded), because the right side might not get evaluated at all. So the ==
is executed first. But precedence plays no part at all in this. If you instead had written the non-short-circuiting a != b | a <= b
, both sides would eventually get executed (with caveats, see below), but there are no guarantees which side gets evaluated first; precedence does not play a part here.
Caveat: the compiler can still just optimize your code and realize that a != b || a <= b
is tautological, and simply replace the entire thing with true
.
CodePudding user response:
From: https://en.cppreference.com/w/cpp/language/operator_logical
You are looking for the part in ( )
Builtin operators && and || perform short-circuit evaluation (do not evaluate the second operand if the result is known after evaluating the first), but overloaded operators behave like regular function calls and always evaluate both operands
So a != b will be evaluated first.
In your case 3 != 3 so the second operand will be evaluated.
if( (5<5) || (5!=5) || (5==5) || (5>5) )
The precedence left to right, so 5<5, goes to next 5!=5 goes to next 5==5 operand if returns true and 5>5 is not evaluated.
CodePudding user response:
As per Microsoft doc,
The operator <=
>=
<
>
has higher precedence than the operator !=
==
. But as you have applied the logical or ||
operator the expression will be executed from left to right.
It will handle it as ( ( a != b ) || ( a <= b ) )
meaning, first compiler will check ( a != b )
, after that, this expression ( a <= b )
and apply logical ||
on the results.