Mitchell Jiang February 2016

PHP - What does "Operator precedence and associativity do not specify an order of evaluation" mean?

I am reading the Operator Precedence section of the PHP Manual. I am confused about (or say, I don't understand the following sentences quite much):

Operator precedence and associativity only determine how expressions are grouped, they do not specify an order of evaluation. PHP does not (in the general case) specify in which order an expression is evaluated and code that assumes a specific order of evaluation should be avoided, because the behavior can change between versions of PHP or depending on the surrounding code.

It also gives two examples to illustrate the undefined order of evaluation.

<?php
$a = 1; 
echo $a + $a++; // may print either 2 or 3
>?

From what I understand, $a evaluats to 1 first because the associativity of the addition operator is left. Then 1 is added to $a++, which evaluates to 1. So, then result should be 2. Why does the comment in the documentation say "may print either 2 or 3"?

The second example is:

<?
$i = 1;
$array[$i] = $i++; // may set either index 1 or 2
?>

Similarly, $i++ evaluates to 1 first because the associativity of the assignment operator is right. Then the value of 1 should be set to the index 2 of the array. Why does the comment say "may set either index 1 or 2"?

The only explanation I can think of is that the order of code in the two examples above can be executed the opposite of what I reasoned.

Any thoughts to help me unravel my confusion will be greatly appreciated.

Answers


Barmar February 2016

Just because an operator is left-associative, it doesn't mean the parameters are evaluated left-to-right. In

$a + $a++

It can evaluate $a first or $a++ first. In the first case, the result is 1 + 1 = 2; in the second case the result is 2 + 1 = 3.

Associativity just specifies how multiple expressions are grouped when they're combined. For instance, if you have

1 - 2 + 3

left-associativity specifies that this is interpreted as

(1 - 2) + 3 = 2

rather than

1 - (2 + 3) = -4

But if this expression had sub-expressions with side effects, it could still evaluate them right-to-left (or in some mixed order).


trincot February 2016

The confusion concerns associativity. Where you say it applies there is no associativity at play.

Look at the given examples:

First example

$a = 1; 
echo $a + $a++; // may print either 2 or 3

You can break down the evaluation of that expression in two steps:

  1. Get the values of $a and calculate $a++
  2. Perform the addition

The precedence rules have something to say about this:

  • The evaluation of $a++ should happen before the evaluation of the addition:
    ++ has higher precedence than +

But that is it.

There is no rule that says that the value of $a should be retrieved before $a++ is evaluated. That is not what left associativity is about.

Associativity

Left (or right) associativity only comes into play when two operators with the same precedence (e.g. twice the same operator) occur one after the other in one expression. For instance

$a = 0
$a++ - 1 - $a++

The first - is guaranteed to be executed before the second, by the left associativity rule.

But, this leaves open the possibility for the following sequence of evaluation:

  1. evaluate the second $a++
  2. evaluate the first $a++
  3. evaluate the first subtraction (required to happen before next step)
  4. evaluate the second subtraction

So, although the associativity rule fixed that step 4 had to come after step 3, there is no rule that dictates the order of the first two steps.

Second example

$i = 1;
$array[$i] = $i++; // may set either index 1 or 2

Again, there is no left associativity at play here. PHP is free to perform the following two steps in either order:

  • evaluate

Post Status

Asked in February 2016
Viewed 2,497 times
Voted 9
Answered 2 times

Search




Leave an answer