why these both post increment in PHP gives the same answer? [duplicate]
Asked Answered
G

3

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 !!!

Genous answered 12/12, 2017 at 6:23 Comment(21)
Post-increment will only add values after the end of the statement. Thats why you're getting the same values in both the cases...Verditer
put another echo $a; at the end to see the actual effect. I assume it has todo with operator precedence, see Example #2. Which version of PHP are you on?Sandalwood
according to your answer then second example should give output 4!Genous
Opcodes - 3v4l.org/iaF9iParietal
@LawrenceCherone Please clear what it is. I am also desperate to know how its happening.Weatherman
How $a+$a++ is equal to $a+$a+$a++ ??Weatherman
im still wonder why both giving answer 3!!!Genous
@LawrenceCherone Yeh its really surprising. It looks such a small thing but unfortunately we don't have any answer for it.Weatherman
Please refer this #22314942Koblas
Surpring, only the $a+$a++ breaks. eval.in/917220Fervor
yes but i really need the answer :PGenous
@LawrenceCherone Its not that much clear to me :(Weatherman
$a = 1; echo $a+ ++$a; //4 figure that one out ;pParietal
I found a few more anomalies in the rabbit hole: sandbox.onlinephpfunctions.com/code/…Ruck
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.Nephridium
Still there is no satisfactory answer that can explain the correct logic behind it.Weatherman
@Sandalwood im using PHP latest versionGenous
Still I'm not satisfied with any answer :(Genous
@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.Ruck
@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 :)Weatherman
its really tough!Genous
A
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.

Anabal answered 12/12, 2017 at 8:19 Comment(11)
The behavior only seems wrong for $a+$a++ - 3v4l.org/9Wp8V as if it's evaluated as pre not post. So it makes the OPs example 2 look off.Parietal
In your first example, $a becomes 2 but in the 2nd one it remain as 1. How?Weatherman
You explained it well but Still I'm not satisfied with your answer. still wonder.Genous
@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.Anabal
@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 =)Anabal
@AmitGupta I clarified by first example by introducing another variable. Should be super clear now what happens.Anabal
@Anabal 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 :DWeatherman
@AmitGupta it works same on all popular PHP versions ( 3v4l.org/HrA95 ), it depends on C++ compilator you (or someone who generated PHP binary file) compiled PHPBorate
@Borate try offline in your systemWeatherman
@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 architectureBorate
@Borate Result is '4' at my end on Windows 7 PHP 7.0.9, Apache 2.0 ServerWeatherman
B
-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
Borate answered 12/12, 2017 at 7:51 Comment(9)
I am afraid this does not answer the question. The question is "why".Ruck
"It's behavior is not definied" - it can work different based on language implementation.Borate
To answer this question adequately, you will need to explain what is happening with the internals of php.Ruck
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.Sanguinary
'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.Borate
IMHO, if you can't read $d = $array[$i++] you shouldn't be a programmerSanguinary
@Sanguinary 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 :)Borate
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".Sanguinary
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.Sanguinary
L
-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.

Locket answered 12/12, 2017 at 6:32 Comment(2)
what about the second example?????Genous
according to your answer then second example should give output 4! $a = 1; ($a+$a+$a++) it not giving the output 4!Genous

© 2022 - 2024 — McMap. All rights reserved.