Reputation: 8772
In code snippet below
int jo=50;
if( jo =(rand()%100), jo!=50)
{
printf("!50");
}
Upvotes: 2
Views: 134
Reputation: 112366
Well, sequence points is the right answer. but let's translate from the textbook-ese.
The comma operator has a special property: it makes sure that what's on its left hand side is evaluated first. So, when you get to the expression
jo =(rand()%100), jo!=50
even though the !=
binds more tightly than ',', so that the expressiojn, fully parenthesized is
(jo =(rand()%100)),(jo!=50)
the first part is evaluated first.
To remember this, you can pronouce or read the comma operator as "and then", so
j0=(rand()%100)
"and then"
jo!=50.
Upvotes: 3
Reputation: 239011
Precedence does not control the order of execution. Precedence only controls the grouping - that is, precedence says what the operands are for each operation, not when each operation happens.
In this example, the precedence of %
is irrelevant due to the parentheses - these say that the operands of %
are rand()
and 100
.
The precedece of ,
being lower than that of =
and !=
tells us that the operands of =
are jo
and (rand()%100)
, and that the operands of !=
are jo
and 50
.
The operands of ,
are then jo = (rand() % 100)
and jo != 50
.
The definition of the ,
operator says that the first operand is evaluated, then there is a sequence point, and then the second operand is evaluated. So this case, jo = (rand() % 100)
is fully evaluated, which stores the result of rand() % 100
into jo
; and then jo != 50
is evaluated. The value of the overall expression is the value of jo != 50
.
Upvotes: 3
Reputation: 488003
It's a mistake to think of "precedence" as "done first".
Consider the following code snippet:
f() + g() + h()
Which has add operation has higher precedence, the one that sums the results of f() and g(), or the one that sums the results of that and h()?
It's a trick question, because there is no need to invoke "precedence" at all. But there is still an order of operations, because function calls in C introduce "sequence points", which is how C allows you to determine "what happens when", as it were.
In your particular code, you have a comma operator—which is quite different from the comma punctuator in function arguments—in this part:
jo = (rand() % 100), jo != 50
The comma operator introduces a sequence point (as does the function call to rand
), so we know that rand
runs and produces a value, then that value % 100
is computed and assigned to jo
, and finally jo
is compared with 50
.
(There is a sequence point after the evaluation of the controlling expression in the if
as well, and one at each statement-ending semicolon.)
Upvotes: 2
Reputation: 121649
The issue is "sequence points":
http://www.angelikalanger.com/Articles/VSJ/SequencePoints/SequencePoints.html
Problematic vs. Safe Expressions
What is it that renders the assignment x[i]=i++ + 1; a problematic one whereas the assignment i=2; is harmless, in the sense that its result is well-defined and predictable? The crux is that in the expression x[i]=i++ + 1; there are two accesses to variable i and one of the accesses, namely the i++, is a modifying access. Since the order of evaluation between sequence points is not defined we do not know whether i will be modified before it will be read or whether it will be read before the modification. Hence the root of the problem is multiple access to a variable between sequence points if one the accesses is a modification.
Here is another example. What will happen here if i and j have values 1 and 2 before the statement is executed?
f(i++, j++, i+j);
Which value will be passed to function f as the third argument? Again, we don't know. It could be any of the following: 3, 4, or 5. It depends on the order in which the function arguments are evaluated.
The common misconception here is that the arguments would be evaluated left to right. Or maybe right to left? In fact, there is no order whatsoever mandated by the language definition.
Upvotes: 3