compilation order and post prefix opertors

淺唱寂寞╮ 提交于 2019-12-05 04:36:23

Before I start, let me point out that one should generally avoid situations where one you both sets and reads a variable within an expression.


First, let's look at operand evaluation order. This isn't defined for many operators, but it is defined for the list operator. It's documented to evaluate its operands in left-to-right order[1]. That means that printf's arguments are evaluated in the following order:

  1. "%d %d %d %d"
  2. $a
  3. ++$a
  4. $a++
  5. $a

The key lies in knowing that $a doesn't place a copy of the value of $a on the stack. It places the scalar itself (a SV*, in C terms). In Perl jargon, we say the stack element is aliased to $a[2]. In computing theory, you'd say the arguments are passed by reference.

And the same goes for ++$a, but $a++ necessarily places a copy of $a on the stack.

This means we can view the above printf call as equivalent to

use Data::Alias qw( alias );

{
    local @_;
    alias $_[0] = "%d %d %d %d";
    alias $_[1] = $a;    # Places $a on the stack.
    alias $_[2] = ++$a;  # Adds one to $a and places $a on the stack.
    alias $_[3] = $a++;  # Places a copy of $a on the stack and adds one to $a.
    alias $_[4] = $a;    # Places $a on the stack.
    &CORE::printf;
 }

By the time $a++ is called, $a contains 6.

By the time printf is called, $a contains 7.


The workaround is to make copies of the values.

$ perl -le'$a = 5; my @b = ($a, ++$a, $a++, $a); print "@b";'
7 7 6 7

$ perl -le'$a = 5; my @b = (0+$a, 0+(++$a), $a++, $a); print "@b";'
5 6 6 7

  1. From perlop, "In list context, it's just the list argument separator, and inserts both its arguments into the list. These arguments are also evaluated from left to right."

  2. From perlsyn, "Any arguments passed in show up in the array @_. Therefore, if you called a function with two arguments, those would be stored in $_[0] and $_[1]. The array @_ is a local array, but its elements are aliases for the actual scalar parameters."

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!