-4

I just started reading C.

Situation :

x = ( y = 3, ( z = ++y + 2 ) + 5 )

It is evaluating y = 3 first then evaluating ( z = ++y + 2 )

My Problem :

It should first evaluate ( z = ++y + 2 ) because the precedence of comma(,) is much less than parenthesis

My way of Thinking :

  1. Due to precedence we select outer parenthesis

  2. Then we need to evaluate parenthesis

  3. Under this (parenthesis) I again started applying precedence rule

  4. So I took inner bracket to evaluate first

P.S. :

This is not a Duplicate

I have already gone through these links but still unable to understand

Behavior of comma operator in C

C comma operator

What does the comma operator , do?

https://learn.microsoft.com/en-us/cpp/cpp/comma-operator

Uses of C comma operator

https://en.wikipedia.org/wiki/Comma_operator

Bhaskar
  • 89
  • 8
  • 2
    You need somebody that reviews your code. Don't code alone. – Hans Passant Jul 09 '18 at 13:23
  • 1
    `,` evaluates left-to-right, the left-hand side argument must be evaluated before the right. I don't see how precedence of parens as a sub-expression of the right-hand side has any significance here. (And indeed that code is horrible.) – Mat Jul 09 '18 at 13:24
  • The comma joins two subexpressions: `y = 3` and `( z = ++y + 2 ) + 5`. The MSDN documentation you linked clearly says: *"Two expressions separated by a comma are evaluated left to right."*. Accordingly, `y = 3` is evaluated before `( z = ++y + 2 ) + 5`. – axiac Jul 09 '18 at 13:25
  • @Mat I wrote this code to understand how comma operator works. Parenthesis have higher precedence then commas and I think we 1st need to select operator(so precedence comes first) – Bhaskar Jul 09 '18 at 13:27
  • @axiac That means Comma operator suppress the precedence of parentheses – Bhaskar Jul 09 '18 at 13:29
  • 2
    @Bhaskar : the rules of operator precedence make `x = ( y = 3, ( z = ++y + 2 ) + 5 )` equivalent to `x = ((y = 3), ((z = ((++y) + 2)) + 5))`. Nothing more or less. – Sander De Dycker Jul 09 '18 at 13:31
  • 3
    @Bhaskar Is this an assignment you need to explain in order to pass your class? If not, just ignore it, throw this expression away, don't waste any of your finite time on this earth trying to understand it. You'll never encounter code like this in a real program. You'd never want to write code like this. I'm one of the more experienced C programmers I know, and I can't be bothered to spend any of my finite time on this earth trying to understand that expression. For all intents and purposes, it's meaningless. – Steve Summit Jul 09 '18 at 13:34
  • 1
    The precedence of operators only tells how the operands and sub-expressions are associated to the operators, not in which order they are evaluated. The precedence says that the comma joins the two sub-expressions I listed in my previous comment. As a simpler example, the precedence of operators in `a*b+c*d` only tells that the operands are grouped as `(a*b)+(c*d)`, it doesn't tell anything about the order of evaluation of `a*b` and `c*d`. They can be evaluated in any order because `+` does not impose an order. The comma operator, on the other hand, requires an evaluation order. – axiac Jul 09 '18 at 13:38
  • 1
    @Bhaskar - It is amazing that people saying *"I just started reading C."* comes here with overly complex code. People having done this for a long time instead writes a lot simpler code that everyone can read and understand. You really ought to aim for stage 2. (Bringing code like this to a code review, other than on April 1st, might be a firing offense). – Bo Persson Jul 09 '18 at 15:01
  • One might ask, "As bad as this code is, if I understand it, won't that make me a better programmer?" Perhaps. By the same token, taking someone who's just learning how to drive, seating him in an F1 racing car, putting him on a go-kart track with turns even tighter than the F1 can navigate, removing one of the car's front wheels, and telling the student to try to drive around the track as fast as he can, while you simultaneously drop large boulders in front of him, *miiiiiiigggghht* teach him something about driving. Or not. – Steve Summit Jul 09 '18 at 15:50

3 Answers3

6

You're confusing operator precedence with order of evaluation.

Operator precedence dictates how subexpressions are grouped. It does not dictate when each operand is evaluated.

The comma operator has a sequence point between its left operand and its right operand. In the case of y = 3, ( z = ++y + 2 ) + 5, that means that y = 3 must be fully evaluated before ( z = ++y + 2 ) + 5 can be evaluated.

Note also in the subexpression ( z = ++y + 2 ) + 5 that there is no guarantee that everything inside the parenthesis are evaluated before everything inside. You only know that ( z = ++y + 2 ) and 5 are evaluated before ( z = ++y + 2 ) + 5 is evaluated. If for example you had (z = ++y + 2) + y this would invoke undefined behavior because the second y could be evaluated before or after the side effect of ++y.

As another example, if you had x = (func1() + 3) + func2(), either func1 could be called first or func2 could be called first since the order of evaluation of operands is unspecified. If both of those functions modified the same global variable, you wouldn't be able to reliably know the value of that variable.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    "sequence point": OP even is lucky that there is one, otherwise we would have had UB due to multiple unsequenced reads/writes of the same data... – Aconcagua Jul 09 '18 at 13:32
4

Precedence and evaluation order are different things. In the expression (a*b) - (c+d), the compiler is free to evaluate (c+d) before (a*b), even though multiplication has higher precedence than addition. But in the expression a,b, as well as the code a;b, the compiler is required to sequence the computation of a before the computation of b.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
1

You are confused between Precedence and Order of Evaluation. Precedence is the priority for grouping different types of operators with their operands.

The comma (,) operator constitute Sequence Point and therefore guarantee a particular order of evaluation for their operands which is left to right.

Order of evaluation

Ordering
......

If a sequence point is present between the subexpressions E1 and E2, then both value computation and side effects of E1 are sequenced-before every value computation and side effect of E2

Rules
.....
2) There is a sequence point after evaluation of the first (left) operand and before evaluation of the second (right) operand of the following binary operators: && (logical AND), || (logical OR), and , (comma).

In this expression:

x = ( y = 3, ( z = ++y + 2 ) + 5 )

First y = 3 will be evaluated first and then ( z = ++y + 2 ) + 5.

H.S.
  • 11,654
  • 2
  • 15
  • 32