Jeevan
Jeevan

Reputation: 8772

Operator precedence in c with %,!=,= and ','

In code snippet below

int jo=50;
if( jo =(rand()%100), jo!=50)
{
    printf("!50");
}   
  1. % has highest precedence so rand()%100 will get executed first
  2. != has the precedence greater than = so jo != 50 should get execute right ?
  3. , has the least precedence still when i execute assignment occurs first then != and then , . I get an output !50 why ??

Upvotes: 2

Views: 134

Answers (4)

Charlie Martin
Charlie Martin

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

caf
caf

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

torek
torek

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

paulsm4
paulsm4

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

Related Questions