develooper Front page | perl.perl5.porters | Postings from February 2023

Re: PERL_RC_STACK branch: first cut

Thread Previous | Thread Next
February 27, 2023 13:12
Re: PERL_RC_STACK branch: first cut
Message ID:
On Mon, 27 Feb 2023 at 13:40, Ruud H.G. van Tol via perl5-porters <> wrote:

> On 2023-02-27 13:17, demerphq wrote:
> > On Mon, 27 Feb 2023 at 12:45, Ruud H.G. van Tol via perl5-porters
> > <> wrote:
> >
> >     I don't see (yet) how/why it should print out "foo".\
> >
> >     Why would you want/expect it to print "foo",
> >     when you are using aliased parameters,
> >     and are deliberately emptying the array?
> >
> >
> > Because the scalar that holds "foo" has been pushed onto the stack
> > independently of the array that originally contains it. The fact that
> > perl aliases arguments is a key part of this bug. If the stack was
> > refcounted the alias would not be freed until the scalar was popped
> > from the stack.
> OK, so then it (partly) comes down to what one interprets (?) as aliasing.

I still think it was fine to print nothing (or to complain about undefined).

I don't understand why you would think that emptying out an array is the
same as undefing a scalar. They aren't the same thing at all.

Consider this code:

perl -MArray::RefElem=av_push -le'my @a=("foo"); my @b; av_push(@b,$a[0]);
$a[0].="x"; @a=(); print $b[0]'

I think we both agree this behaves correctly. (I hope).  In this case we
are also storing an alias into @b, but it is properly refcounted. So when
we clear @a it does not free $a[0], as the scalar in $a[0] has also been
stored in @b.

Here is an even closer analog:

perl -MArray::RefElem=av_push -le'my @stack; my @a=(foo); av_push
@stack,\@a; av_push @stack, $a[0]; @{$stack[0]}=(); print $stack[1]'

This example and the stack example from the earlier post are pretty much
functionally equivalent and should behave the same, and with Dave's fix
they do. Without it obviously they dont. Notice that clearing @{$stack[0]}
does not /free/ the scalar $a[0], because it also stored in $stack[1],
instead it merely evicts it from @a as part of emptying @a. That is as
expected because $stack[1] holds a refcount on it. The bug that Dave is
fixing is that the perl stack didnt do that refcount increment, so the var
would get freed prematurely.

So unless you expect the two examples here to do something other than what
they do I think you have a flaw in your mental model about what the
original example was doing.  Which is not that surprising, this bug has
been around a long time and I imagine people are somewhat habituated to it.


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About