2

I am trying to figure out what order of evaluation is. I really don't understand point of order of evaluation. Evaluate it operands, subexpressions, expressions or what ?

I was trying to do some research and look at the difference between gcc and vc compiler, but after a lot of time spend on this research, I still don't understand what order of evaluation does.

Let's take an example:

-----------------First example-----------------

int i = 1, j; j = (i = 5) + (i = 6);

gcc and visual studio result: j = 12

How I think order of evaluation works here (looks like left to right):

  1. First is evaluated operand j -> there is some random number in this variable.

    j = (i = 5) + (i = 6);

  2. Then is evaluated operand i -> i (with value 1)

    j = (i = 5) + (i = 6);

  3. Then is evaluated constant 5 -> 5

    j = (i = 5) + (i = 6);

  4. Then is evaluated whole subexpression (i = 5) -> i (with value 5)

    j = (i) + (i = 6);

  5. Then is evaluated operand i -> i (with value 5)

    j = (i) + (i = 6);

  6. Then is evaluated constant 6 -> 6

    j = (i) + (i = 6);

  7. Then is evaluated whole subexpression (i = 6) -> i (with value 6)

    j = (i) + (i);

  8. After all order of evaluation, here comes precedence and associativity and everything calculates.

    (j = ((i) + (i))); -> (j = ((6) + (6))); -> j = 12

-----------------Second example-----------------

int x = 1, y = 2, z = 5; x = (y = 3, (z = ++y + 2) + 5);

gcc and visual studio result: x = 11

How I think order of evaluation works here (looks like left to right):

  1. First is evaluated operand x -> x (with value 1)

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

  2. Then should be evaluated subexpression (y = 3, (z = ++y + 2) + 5). Also comma says y = 3 must be evaluated before (z = ++y + 2) + 5
  3. So then is evaluated operand is y -> y (with value 2)

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

  4. Then evaluated is constant 3 -> 3

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

  5. Then evaluated is whole subexpression (y = 3) -> y (with value 3)

    x = (y, (z = ++y + 2) + 5); !!!This is pretty weird, because according to example y = 3 is not subexpression

  6. Then evaluated is operand z -> z (with value 5)

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

  7. Then evaluated is operand (or subexpression, IDK what it is) ++y -> y (with value 4)

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

  8. Then evaluated is constant 2 -> 2

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

  9. Then evaluated is whole subexpression (z = ++y + 2) -> z (with value 6)

    x = (y, (z) + 5);

  10. Then evaluated is constant 5 -> 5

    x = (y, (z) + 5);

  11. Then evaluated is whole subexpression (y = 3, (z = ++y + 2) + 5) -> 11

    x = (11);

  12. After all order of evaluation, here comes precedence and associativity and everything calculates.

    (x = (11)); -> x = 11

-----------------Third example-----------------

int x = 1, y = 2, z = 5; x = (y = 3) + (y = 3) + (y = 5);

gcc result: x = 11

visual studio result: x = 15

This "explanation" of this example will be fast....

How I think order of evaluation works here for gcc (looks like left to right):

I think gcc save value instead of variable, but why?????

  1. x = (y = 3) + (y = 3) + (y = 5); x = (3) + (3) + (5); //saves value instead of variable????? x = 15

How I think order of evaluation works here for visual studio (looks like left to right):

  1. x = (y = 3) + (y = 3) + (y = 5); x = (y) + (y) + (y); //Last value of y was 5, so...... x = 5 + 5 + 5 x = 15

So everything confuses me and this is just really bad research cause I don't understand it.

So I ask you:

  1. What order of evaluation does ? Does operands, subexpressions, expressions or what ? If all, is operand evaluated before subexpression and subexpression before expression ?

  2. Is order of evaluation related to precedence and associativity (maybe for some compilers)

  3. Is order of evaluation done before or after precedence and associativity ?

  4. Why sometimes (like in third example) it looks like compiler saves value instead of variable ? Also this can be wrong cause it can save something completely different, lol....

According to me, I completely wrong what I wrote up - it doesn't make any sense.

Thank you in advance for your answers

Malan Olan
  • 49
  • 3
  • 1
    `x = (y = 3) + (y = 3) + (y = 5);` is really only interesting academically. setting `y` to 3 different values in the same expression would be pathological in practice. I wonder if its behavior is even defined. – erik258 May 20 '20 at 23:39
  • @DanielFarrell it's not, that's why VC is allowed to answer 15 – Caleth May 20 '20 at 23:42
  • @DanielFarrell Setting `y` to 3 different values in the same expression would be textbook ***undefined behavior***. – Marco Bonelli May 20 '20 at 23:42
  • evaluating the left-hand side of an `=` expression does not retrieve the stored value. It determins where in memory the new value will be stored. – M.M May 20 '20 at 23:48
  • Upvoted for effort, but closed as a duplicate. – dbush May 20 '20 at 23:48
  • The second example is not undefined behaviour, but this is too broad for a single question, generally you should stick to 1 question per question – M.M May 20 '20 at 23:50

1 Answers1

0

You've got textbook undefined behaviour.

It is not required to make sense. It is not required to be consistent between compilers, compiler versions, nor even between runs of the same program.

Caleth
  • 52,200
  • 2
  • 44
  • 75