http://www.perlmonks.org?node_id=11111637


in reply to When aliasing sub arguments to @_ elements, PADTMP, READONLY flags are copied inconsistently

$_[0] is not a copy. It's literally the same scalar that was passed as an argument. That means the first 1+1 produced a read-only scalar and the second one didn't.

We can see some differences in the generated code.

$ perl -MO=Concise,-exec -MDevel::Peek -we'Dump 1; sub foo{Dump $_[0]; +$_[0]=1} foo(1)' 1 <0> enter 2 <;> nextstate(main 44 -e:1) v:{ 3 <$> const[IV 1] s 4 <2> Devel_Peek_Dump vK/1 5 <;> nextstate(main 46 -e:1) v:{ 6 <0> pushmark s 7 <$> const[IV 1] sM 8 <#> gv[IV \&main::foo] s 9 <1> entersub vKS a <@> leave[1 ref] vKP/REFC -e syntax OK
$ perl -MO=Concise,-exec -MDevel::Peek -we'Dump 1+1; sub foo{Dump $_[0 +];$_[0]=1} foo(1+1)' 1 <0> enter 2 <;> nextstate(main 44 -e:1) v:{ 3 <$> const[IV 2] s/FOLD 4 <2> Devel_Peek_Dump vK/1 5 <;> nextstate(main 46 -e:1) v:{ 6 <0> pushmark s 7 <$> const[IV 2] sM/FOLD 8 <#> gv[IV \&main::foo] s 9 <1> entersub vKS a <@> leave[1 ref] vKP/REFC -e syntax OK

So it appears that a folded constant (FOLD) in lvalue context (M) returns a writable scalar.

We can also see the difference when using the referencing operator or foreach, as they also also impose an lvalue context.

$ perl -MDevel::Peek -e'Dump(${\1})' SV = IV(0x8549e4010) at 0x8549e4020 REFCNT = 1 FLAGS = (IOK,READONLY,PROTECT,pIOK) IV = 1 $ perl -MDevel::Peek -e'Dump(${\(1+1)})' SV = IV(0x7ed5d4d610) at 0x7ed5d4d620 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 2 $ perl -MDevel::Peek -e'Dump($_) for 1' SV = IV(0x151c4b8240) at 0x151c4b8250 REFCNT = 2 FLAGS = (IOK,READONLY,PROTECT,pIOK) IV = 1 $ perl -MDevel::Peek -e'Dump($_) for 1+1' SV = IV(0x567114cd90) at 0x567114cda0 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 2

I believe this is intentional. Addition normally produces a writable scalar, and those semantics are being preserved even when the operands of the addition are constants.

  • Comment on Re: When aliasing sub arguments to @_ elements, PADTMP, READONLY flags are copied inconsistently
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: When aliasing sub arguments to @_ elements, PADTMP, READONLY flags are copied inconsistently
by vr (Curate) on Jan 20, 2020 at 18:59 UTC

    Thank you all for useful links and answers, I should have done better research to at least find ref to read-only alias ... why?, which itself links far further into the past. Still not sure how to justify why with foo(1+1) the $_[0] is OK to be writeable, but with foo(1) it should die. Following previous discussion, the impression now is that it's either not a bug but vague (because of dynamic language(?)) area, or bug of very low priority, fixing of which can break/slower existing code (?).

    As to from where I started (foo(pack 'P', $data)), with hindsight, of course $_[0] is "pointable" for as long as staying within a sub, and returning that pointer to outside is entirely programmer's (my) fault, Perl couldn't help :(