Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Re: Operator Associative in Perl

by ikegami (Pope)
on Jun 03, 2009 at 15:37 UTC ( #768049=note: print w/replies, xml ) Need Help??

in reply to Operator Associative in Perl

there is no associative for '++' and '--' operator

There are two major mistakes there.

  • You're actually concerned about the order in which the operands of the list operator (,) are evaluated.

  • Operand evaluation order has nothing to do with operator associativity (which determines precedence of instances of operators with the same precedence).

While Perl doesn't document its operand evaluation order, it always evaluates operands from left to right for left-associative operators and exponentiation (**), and from right to left for assignments operators.

This case is no exception. There are two characteristics (features?) of Perl that cause the result you observe:

  • Perl passes arguments to functions and subs by reference.

  • $a, --$a and ++$a return $a as an l-value.

So, that means

is basically equivalent to
do { local @_; alias $_[0] = "%d%d%d%d%d\n"; alias $_[1] = $a++; # Returns new value 5, $a=6 alias $_[2] = $a--; # Returns new value 6, $a=5 alias $_[3] = ++$a; # Returns $a (lvalue) $a=6 alias $_[4] = --$a; # Returns $a (lvalue) $a=5 alias $_[5] = $a; # Returns $a (lvalue) $a=5 \&printf; }
When printf gets the values from @_, it sees
  • 5
  • 6
  • 5 (the current value of $a)
  • 5 (the current value of $a)
  • 5 (the current value of $a)

When I run the same program in C, I got, 45555. Please explain how it is working?

C leaves the operand evaluation order up to the compiler. Results will vary from compiler to compiler. It looks like yours passed by reference, evaluating from right to left.

Replies are listed 'Best First'.
pre and post increment of subroutine arguments
by ig (Vicar) on Jun 04, 2009 at 21:37 UTC

    I find the difference between $a++ and ++$a as subroutine arguments to be quite interesting/surprising.

    In a subroutine the elements of @_ are usually aliases to the arguments of the subroutine call, allowing the subroutine to modify the caller's variables.

    In the case of ++$a, the corresponding element of @_ is a reference to the same IV as $a but in the case of $a++ it is a reference to a new IV, effectively preventing the subroutine from modifying the caller's variable. In both cases the array element is an lvalue (i.e. it can be modified), but only in the case of pre-increment can the subroutine modify the caller's variable.

    Using pre/post increment/decrement on an argument to a subroutine that attempts to modify that argument is not a good thing to do because the order of execution is not defined. None the less, the difference in implementation is interesting.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://768049]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2021-01-26 06:44 GMT
Find Nodes?
    Voting Booth?