Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

How about this for $i=$i++

by jynx (Priest)
on Apr 30, 2002 at 01:54 UTC ( #162977=note: print w/replies, xml ) Need Help??

in reply to $i=$i++

This is probably completely wrong, but...

What i think is happening is this: the reference to the variable $i is being modified by the auto-(in|de)crement operators before the addition operation because of the precedence table. The reference then gets updated for the left $i for a right-side auto-increment because we're dealing with a reference to the actual variable, not a hard-coded number -- and in the case of the post-increment, because of a bug.

Let's say we have the expression

$a + ++$a
This should leave $a at the value 1, but it should evaluate to 1. It evaluates to 2! Because the pre-increment updates the reference to $a on the left side of the addition operator as well. This is fine if it gets documented, but the following is a straight bug:
0 + $a++
We get a return value of 0, and $a is set to 1 as it should be. However if $a is on the left side:
$a + $a++
We get a return value of 1! $a is still set to 1 as it should be. If instead of $a we use some other (zeroed) variable it evaluates to 0 correctly. Somewhere Perl is messing up what happens on a right-side post-increment if the same variable is being added to itself. Maybe it's adding 1 to the left side even if it's a post-increment?

So, to explain the strange ++$a + $a++ i think it works like this:

  1. the code is parsed, the ++'s get the precedence to go first
  2. addition being a left-wise operator, ++$a gets evaluated first; $a gets ++'d to 1
  3. $a++ generates a post-decrement after the statement is over and increments the left-side (erroneously)
  4. the values (2 + 1?) are added returning 3
  5. the post-decrement code is run, and $a is now 2

i could be wrong :/

Here's what i ran with the results i obtained:

#!/usr/bin/perl -w use strict; for $b ( '$a++ ', '0 + $a++', '0 + ++$a', '++$a + $a', '$a + ++$a', '$a + $a++', '++$a + $a++', '$a++ + ++$a', '$a+=$a++' ) { $a = 0; print "$b\t=", eval($b), "\t\$a= $a\n"; } __END__ # results: $a++ =0 $a= 1 0 + $a++ =0 $a= 1 0 + ++$a =1 $a= 1 ++$a + $a =2 $a= 1 $a + ++$a =2 $a= 1 $a + $a++ =1 $a= 1 ++$a + $a++ =3 $a= 2 $a++ + ++$a =2 $a= 2 $a+=$a++ =1 $a= 1
That's a bug imho (though i could be wrong; better explenations anyone?)

hope this helps,

update: Hmmm, even stranger.

If we take

$a + $a + $a++ # = 0 (correct) $a + $a + ++$a # = 1 (correct) $a + $a++ + $a # = 2 (the trailing $a has no effect maybe?) $a + ++$a + $a # = 3 (the ++ effects previous $a as before?)

So the first addition is probably becoming zero before the second addition is messing it up? And to further confuse things:

$a + $a + ++$a + $a++ # = 2 (correct!) 0 + ++$a + $a++ # = 3 (d'oh!)
i think at this point i've gone too far...

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://162977]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (10)
As of 2018-03-22 16:01 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (279 votes). Check out past polls.