in reply to Why does the first $c evaluate to the incremented value in [$c, $c += $_] ?

Even simpler:
my $c = 2; my @a = ($c, $c+=1); print "@a"; # prints 3 3
Similarly:
my @a = ($c, ++$c); # @a is now (3, 3)
But:
@a = ($c, $c++) # @a is now (3, 2) !!!
Do you get it? In the first two cases, the value of $c is modified before the array gets populated. In the last case, because of the use of the post-increment operator, $c is incremented only after the second value is stored into the array, but before the first value is stored into the array.

Replies are listed 'Best First'.
Re^2: Why does the first $c evaluate to the incremented value in [$c, $c += $_] ?
by runrig (Abbot) on Mar 04, 2014 at 21:36 UTC
    Using the same variables multiple times on the same line that you use pre and post increment on is fun to play with, but never depend on the order of operations.
Re^2: Why does the first $c evaluate to the incremented value in [$c, $c += $_] ?
by ikegami (Patriarch) on Mar 06, 2014 at 15:59 UTC

    $c is incremented only after the second value is stored into the array,

    That's not true. The order in which things happen:

    1. $c
    2. $c
    3. post-increment
    4. my @a
    5. list assign

    @a doesn't even exist at the point you say values are assigned to it.

    >perl -MO=Concise,-exec -e"my @a = ( $c, $c++ );" 1 <0> enter 2 <;> nextstate(main 1 -e:1) v:{ 3 <0> pushmark s 4 <#> gvsv[*c] s # $c 5 <#> gvsv[*c] s # $c 6 <1> postinc[t4] sK/1 # post-increment 7 <0> pushmark s 8 <0> padav[@a:1,2] lRM*/LVINTRO # my @a 9 <2> aassign[t5] vKS/COMMON # list assignment a <@> leave[1 ref] vKP/REFC -e syntax OK
Re^2: Why does the first $c evaluate to the incremented value in [$c, $c += $_] ?
by linuxer (Curate) on Mar 04, 2014 at 21:29 UTC
    Well, but what about this? It does not look like your third example worked...
    $ perl -wlE 'my $x=1; my @A=($x, $x++); say join $/, @A;' 2 1

      I believe this falls into the undefined behaviour of auto increment operator :

      Note that just as in C, Perl doesn't define when the variable is incremented or decremented. You just know it will be done sometime before or after the value is returned. This also means that modifying a variable twice in the same statement will lead to undefined behavior.
      So because of the precedence list, you know the right part will be run first, and the left part after that, but when exactly the variable will be incremented is left to Perl's implementation.

        Yes, you are right. In C, if you write:
        c = c++;
        the behavior is not defined by the C standard. Which does not mean that the compiler will return an undefined value. Just the implementer of the compiler is free to do whatever she or he wants. And I remember very well having tried it about 16 years ago with GCC under Linux and another compiler under Windows and having obtained the original value of c for one of them and the incremented value of c for the other (although I do not remember which one gave what). For this type of things, the Perl syntax is rooted in C, but, in a certain way, the behavior is not imposed by a standard which may be silent about certain edge cases, but is sort of defined by the Perl compiler itself. The Perl compiler gives the logical result that I would expect (although what the logical result should be might be considered debatable):
        my $c = 2; $c = $c ++ ; # $c is now 2 $c = ++$c ; # $c is now 3
        And it seems to me that using $c and $c+=1 in the same expression falls into the same category as using $c and $c++ (or ++c) in the same expression, something not very well defined, which is why I also brought those additional examples. Your explanation using operator precedence does make sense (I had not seen it when I posted my examples), but it might simply just be one of those not well-defined behavior cases.
      Sorry, you are right, I originally made a mistake when copying the values, my third example gives (3, 2), not (2, 3) as I originally typed by mistake. I almost immediately corrected it, but it appears you had time to see it before I corrected my error, even though I corrected within 2 minutes of the original post.