2

I read the PHP.net docs which states:

Operator ** has greater precedence than ++.

But when I run this code I get unexpected output:

<?php
$a = 2;
echo(++ $a ** 2); 
// output: 9, means: (++$a) ** 2
// expected: 5, means: ++($a ** 2)

Can you help me get it clear why that happens? Thanks!

Dmitriy Lezhnev
  • 801
  • 2
  • 10
  • 18
  • Maybe try to position the pluses after the `$a` - `($a++ ** 2)`. `++$i` is pre-increment whilst `$i++` post-increment. – GrumpyCrouton Jul 19 '17 at 19:16
  • Yes, your code works as expected (exponent first, then increment). I wonder why my code does not (at least comparing to what docs say). – Dmitriy Lezhnev Jul 19 '17 at 19:18
  • 1
    _Operator precedence and associativity only determine how expressions are grouped, they do not specify an order of evaluation._ – AbraCadaver Jul 19 '17 at 19:23
  • 1
    AbraCadaver that makes sense. I found this post on the matter: https://gist.github.com/nikic/6699370 – Dmitriy Lezhnev Jul 19 '17 at 19:24
  • `echo($a++ ** 2);` gives me `4` and then `echo($a)` gives me 3. So PHP internally evalutes `($a ** 2)` and returns the result. at a later stage it updates the value of `$a`. – Sander Visser Jul 19 '17 at 20:30
  • @DmitriyLezhnev You really should select an answer if any of them have helped you. – GrumpyCrouton Jul 24 '17 at 12:45

4 Answers4

4

This is because ++$a is a pre-increment, and $a++ is a post-increment.

You can read more about this here

Also,

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.

From: PHP Operator Precedence

Community
  • 1
  • 1
GrumpyCrouton
  • 8,486
  • 7
  • 32
  • 71
  • `echo($a++ ** 2);` gives me the same value as `echo($a ** 2);` (php 7.1) this seams to be invalid.. – Sander Visser Jul 19 '17 at 20:22
  • very interesting `echo($a++ ** 2);` gives me `4` but then `echo($a)` gives me `3`. So php first does the `($a ** 2)` and returns that result. after that it sets the valid value of `$a` internally – Sander Visser Jul 19 '17 at 20:27
  • Well the code isn't setting `$a++` to equal anything, in other words, `$a` doesn't actually change, as in not stored back into it's original value - unless I misunderstood your comment – GrumpyCrouton Jul 19 '17 at 20:41
1

I'm pretty sure, that the documentation is wrong here.

Operator ** has greater precedence than ++.

This statement seems in contradiction with how grouping obeys to operator precedence.

Operator precedence and associativity only determine how expressions are grouped, they do not specify an order of evaluation.

In fact if we group ** before ++, we obtain ++($a ** 2), like it is stated in the question. But this expression is not even valid, because the ++ operator can only be used for a variable, but not for an expression.

The fact that ++ is only valid for a variable implies that no operator with two operands can have higher precedence.

Lorenz Meyer
  • 19,166
  • 22
  • 75
  • 121
0

What seems to happening is that the Post/Pre increments are evaluated outside the operation. So the ** is executed and the result is returned.

  • For a post increment the $a variable is updated after the operation.
  • For a pre increment the $a variable is updated before the operation.

So the documentation

Operator ** has greater precedence than ++.

Seems a little bit strange to me.

After some searching this is also mentioned in the comments: http://php.net/manual/en/language.operators.increment.php#119098

Ow and in the documentation itself.

<?php
// POST
$a = 2;
echo($a ** 2);      // 4
echo(PHP_EOL);
echo($a++ ** 2);    // 9
echo(PHP_EOL);
echo($a);           // 3
echo(PHP_EOL);
echo(PHP_EOL);

// PRE
$a = 2;
echo($a ** 2);      // 4
echo(PHP_EOL);
echo(++$a ** 2);    // 4
echo(PHP_EOL);
echo($a);           // 3
echo(PHP_EOL);
echo(PHP_EOL);
Sander Visser
  • 4,144
  • 1
  • 31
  • 42
  • Isn't this basically the same as my answer? Except mine explains that precedence doesn't actually set the order of evaluation – GrumpyCrouton Jul 19 '17 at 20:43
  • No because `echo($a++ ** 2)` we would except the answer `5` not `4` – Sander Visser Jul 19 '17 at 20:44
  • 1
    So I take out the code I supplied and we have the same answer, and yours doesn't explain that precedence != evaluation, therefore your answer doesn't actually answer the question asked – GrumpyCrouton Jul 19 '17 at 20:45
  • Yes, in the link to the stackoverflow answer in your answer you can see the table :) that's the most important part – Sander Visser Jul 19 '17 at 20:47
  • Yep haha I was a bit confused by the `4`, but still a question remains when does the `**` operator get precedence over `++` documented on the page linked by OP – Sander Visser Jul 19 '17 at 20:53
  • Again, precedence != evaluation - precedence doesn't determine that. You can force evaluation by wrapping it in parenthesis – GrumpyCrouton Jul 19 '17 at 20:55
-1

Spaces, this is why!

++ $a ** 2 is different from ++$a ** 2, that is also different from ++$a**2

Gabriel Caruso
  • 789
  • 1
  • 7
  • 17