8

I am trying to run the following code in PHP through localhost, but its giving the unexpected output!

<?php
    $a = 1;
    echo ($a+$a++); // 3
?>

//answer is 3 but answer should be 2 due to post increment here is another code and it gives the same answer! why?

<?php
   $a = 1;
   echo ($a+$a+$a++);
?>

//answer is still 3 !!!

Deep Kakkar
  • 5,831
  • 4
  • 39
  • 75
RAK
  • 109
  • 7
  • Post-increment will only add values after the end of the statement. Thats why you're getting the same values in both the cases... – Yash Parekh Dec 12 '17 at 06:25
  • 1
    put another `echo $a;` at the end to see the actual effect. I assume it has todo with [operator precedence](http://uk3.php.net/manual/en/language.operators.precedence.php), see Example #2. Which version of PHP are you on? – BNT Dec 12 '17 at 06:25
  • according to your answer then second example should give output 4! – RAK Dec 12 '17 at 06:27
  • 1
    Opcodes - https://3v4l.org/iaF9i – Lawrence Cherone Dec 12 '17 at 06:33
  • @LawrenceCherone Please clear what it is. I am also desperate to know how its happening. – Amit Gupta Dec 12 '17 at 06:41
  • How $a+$a++ is equal to $a+$a+$a++ ?? – Amit Gupta Dec 12 '17 at 06:42
  • im still wonder why both giving answer 3!!! – RAK Dec 12 '17 at 06:46
  • @LawrenceCherone Yeh its really surprising. It looks such a small thing but unfortunately we don't have any answer for it. – Amit Gupta Dec 12 '17 at 06:50
  • 1
    Please refer this https://stackoverflow.com/questions/22314442/php-operator-precedence-undefined-order-of-evaluation – dhi_m Dec 12 '17 at 07:05
  • Surpring, only the `$a+$a++` breaks. https://eval.in/917220 – LF00 Dec 12 '17 at 07:07
  • yes but i really need the answer :P – RAK Dec 12 '17 at 07:09
  • @LawrenceCherone Its not that much clear to me :( – Amit Gupta Dec 12 '17 at 07:10
  • `$a = 1; echo $a+ ++$a; //4` figure that one out ;p – Lawrence Cherone Dec 12 '17 at 07:27
  • 1
    I found a few more anomalies in the rabbit hole: http://sandbox.onlinephpfunctions.com/code/c91f740a0e8ef2f807d608dc2ef52976e9dbc4bb – mickmackusa Dec 12 '17 at 07:47
  • 1
    A simple echo of `$a` added to the first example: `$a = 1; echo ($a+$a++); echo "_"; echo $a;`. Surprise! It yields `3_2`. It seems that that behavior occurs from PHP version 5.1. – MC Emperor Dec 12 '17 at 08:05
  • Still there is no satisfactory answer that can explain the correct logic behind it. – Amit Gupta Dec 12 '17 at 10:00
  • @BNT im using PHP latest version – RAK Dec 12 '17 at 11:06
  • Still I'm not satisfied with any answer :( – RAK Dec 12 '17 at 11:11
  • @user8196822 That's okay, don't settle. If you are not happy, don't feel pressured to reward anyone. What you can do is drill down and express exactly what type of response you want to see posted. Perhaps you would like to see a version-by-version chart/graph/table of which php versions honor the expected behavior of echoing a post-incremented variable. Maybe you'd like to see the breakdown of the php source code which compares the differences between versions. Do you want to see links to lodged bug reports? Do you want it all? It is only fair that you state what you desire. – mickmackusa Dec 12 '17 at 13:11
  • @LawrenceCherone $a = 1; echo $a+ ++$a; it must be 3 but it's 4 :p this is something related with PHP versions having unexpected behavior out of our logic, that's what comes out of all this :) – Amit Gupta Dec 12 '17 at 15:41
  • its really tough! – RAK May 07 '19 at 04:47

3 Answers3

1

The PHP manual says the following:

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.

So what this comes down to, PHP doesn't explicitly define what the end-result is of those types of statements, and it may even change between PHP versions. We call this undefined behavior, and you shouldn't rely on it.

You might be able to find an exact reason somewhere in the source why this order is chosen, but there might not be any logic to it.

Your two examples are being evaluated as follows:

<?php
  $a = 1;
  echo ($a + $a++); // 3
?>

Really becomes:

<?php
  $a = 1;
  $b = $a++;
  echo ($a + $b); // a = 2, b = 1
?>

Your second example:

<?php
  $a = 1;
  echo ($a + $a + $a++); // 3
?>

Becomes:

<?php
  $a = 1;
  $b = $a + $a;
  $a++;
  echo $b + $a; // 3
?>

I hope this kind of makes sense. You're right that there's no hard logic behind this.

Evert
  • 93,428
  • 18
  • 118
  • 189
  • 1
    The behavior only seems wrong for `$a+$a++` - https://3v4l.org/9Wp8V as if it's evaluated as pre not post. So it makes the OPs *example 2* look off. – Lawrence Cherone Dec 12 '17 at 08:31
  • 1
    In your first example, $a becomes 2 but in the 2nd one it remain as 1. How? – Amit Gupta Dec 12 '17 at 09:57
  • 1
    You explained it well but Still I'm not satisfied with your answer. still wonder. – RAK Dec 12 '17 at 11:13
  • @AmitGupta i guess my example was a bit poor. What I meant to illustrate is in the first example ($a++) returns one, but after returning one it increments $a (so it becomes 2) which then gets added to the incremented. number. – Evert Dec 12 '17 at 22:08
  • @user8196822 sorry but I'm not going to hunt down the exact PHP source that's exactly responsible or this. I explained how, I explained why and that's all you'll get from me =) – Evert Dec 12 '17 at 22:09
  • @AmitGupta I clarified by first example by introducing another variable. Should be super clear now what happens. – Evert Dec 12 '17 at 22:10
  • @Evert Yes its now much clear that it all depends upon PHP versions. The logic behind both the examples are different. Last line make things more clear that there's no hard logic behind this :D – Amit Gupta Dec 13 '17 at 02:04
  • @AmitGupta it works same on all popular PHP versions ( https://3v4l.org/HrA95 ), it depends on C++ compilator you (or someone who generated PHP binary file) compiled PHP – JerzySBG Dec 13 '17 at 07:42
  • @JerzySBG try offline in your system – Amit Gupta Dec 13 '17 at 07:47
  • @AmitGupta Result is '3' on Windows 7 PHP 5.6, Linux Fedora PHP 7.0, Linux Debian 8 PHP 5.6, Linux Mint PHP 7.1, but it can be '2', if you compile PHP on some other compilator/processor architecture – JerzySBG Dec 13 '17 at 07:54
  • @JerzySBG Result is '4' at my end on Windows 7 PHP 7.0.9, Apache 2.0 Server – Amit Gupta Dec 13 '17 at 09:12
-1

BEHAVIOR OF INCREMENT OPERATION IN SAME LINE WITH CALCULATION IS NOT DEFINIED!

Compilator can generate different code then you expect.


Simple answer from my teacher:

NEVER USE INCREMENT/DECREMENT OPERATOR IN SAME LINE WITH CALCULATIONS!

It's behavior is undefined - computers calculate in different order then humans.

GOOD:

$d = $i++;
$i++;
for ($i = 0; $i < 5; $i++)

CAN BE A PROBLEM (you can read it wrong):

$d = $array[$i++];

WILL BE A PROBLEM:

$d = $i++ + 5 - --$k;

EDIT:

I wrote same code in C++. Checked Assembler code and result is as I said: Math with increment is not logic for people, but you can't say that someone implemented it wrong.

As someone posted in comment:

line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   ASSIGN                                                   !0, 1
   3     1        POST_INC                                         ~2      !0
         2        ADD                                              ~3      !0, ~2
         3        ECHO                                                     ~3
  16     4      > RETURN                                                   1

//$a = 1;
//echo ($a+$a++);


line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   ASSIGN                                                   !0, 1
   3     1        ADD                                              ~2      !0, !0
         2        POST_INC                                         ~3      !0
         3        ADD                                              ~4      ~2, ~3
         4        ECHO                                                     ~4
         5      > RETURN                                                   1

//$a = 1;
//echo ($a+$a+$a++);

Translated to human language:

$a = 1;
echo ($a + $a++);

// After changing to 'computer logic' (ASM):

$c = 1; // for increment operation
$b = $a; // keep value 'before' add +1 operation
$a += $c; // add +1 operation
$d = $a + $b; // calculate value for 'echo'
echo $d; // print result
JerzySBG
  • 109
  • 8
  • 2
    I am afraid this does not answer the question. The question is "why". – mickmackusa Dec 12 '17 at 07:52
  • "It's behavior is not definied" - it can work different based on language implementation. – JerzySBG Dec 12 '17 at 07:53
  • 1
    To answer this question adequately, you will need to explain what is happening with the internals of php. – mickmackusa Dec 12 '17 at 07:54
  • 1
    There's no problem mixing increment operators and calculations _so long as they don't apply to the same variable_. Your `$d = $array[$i++]` is a perfectly common idiom. – Alnitak Dec 12 '17 at 09:34
  • 'CAN BE A PROBLEM (you can read it wrong)" - YOU can read it wrong. I meant that code work as expected, but some people may interpret it wrong. You can use 1 more line of code '$i++;' and make code much easier to read for everyone. – JerzySBG Dec 12 '17 at 09:38
  • 1
    IMHO, if you can't read `$d = $array[$i++]` you shouldn't be a programmer – Alnitak Dec 12 '17 at 12:40
  • @Alnitak It's related to software engineering. You can write all your code in 1 line, but sooner (if you work on projects which have MBs of code) or later I will get your code from my client with text like 'please make it work again, nobody got idea how it works!' and then I will refactor it all :) – JerzySBG Dec 13 '17 at 07:59
  • Sorry to go ad-hominem, but I've been programming for over 35 years, and I've got a Masters in Engineering and Computer Science from Oxford University and have built numerous large software projects and always pay particular attention to code structure and readability. You're a "PHP developer". – Alnitak Dec 13 '17 at 09:22
  • As for `$d = $i++ + 5 - --$k;` - whilst that might not be particularly readable (and I _wouldn't_ write that myself), it is actually perfectly well defined because none of the variables that are using increment / decrement operators are re-used anywhere else in the expression. If you're being taught otherwise, they're wrong. – Alnitak Dec 13 '17 at 09:25
-3

Its because the ++ sign is an incremental operator to a variable. So your

$a = 1

$a++ = 2

($a+$a++) = (1+2) = 3

Thats why it shows 3 as the answer.

jun drie
  • 860
  • 7
  • 14