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

Re: [perl #20933] \substr reuses lvalues (sometimes)

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
February 14, 2003 04:55
Subject:
Re: [perl #20933] \substr reuses lvalues (sometimes)
Message ID:
20030214125124.A5504@fdgroup.com
On Fri, Feb 14, 2003 at 12:14:57PM +0100, Slaven Rezic wrote:
> "Joshua b.Jore (via RT)" <perlbug-followup@perl.org> writes:
> > The following code prints "abbb" when it should be "abab". BrowserUK
> > of perlmonks.org clued me into this error.
> > 
> > $s = "ab";
> > $r[0] = \ substr $s, 0, 1;
> > $r[1] = \ substr $s, 1, 1;
> > print ${ $r[0] };
> > print ${ $r[1] };
> > 
> > $r[$_] = \ substr $s, $_, 1 for (0, 1);
> > print ${ $r[0] };
> > print ${ $r[1] };
> > 
> 
> The patch below fixes the problem. The fix is not very elegant,
> though.
> 
> --- bleedperl/pp.c	Sun Feb  2 18:59:19 2003
> +++ bleedperl2/pp.c	Fri Feb 14 11:13:40 2003
> @@ -476,6 +476,17 @@ S_refto(pTHX_ SV *sv)
>      }
>      else if (SvPADTMP(sv) && !IS_PADGV(sv))
>          sv = newSVsv(sv);
> +    else if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'x') {
> +	/* [perl #20933] */
> +	SV* new_sv = newSVsv(sv);
> +	sv_upgrade(new_sv, SVt_PVLV);
> +	sv_magic(new_sv, Nullsv, PERL_MAGIC_substr, Nullch, 0);
> +	LvTYPE(new_sv) = 'x';
> +	LvTARG(new_sv) = SvREFCNT_inc(LvTARG(sv));
> +	LvTARGOFF(new_sv) = LvTARGOFF(sv);
> +	LvTARGLEN(new_sv) = LvTARGLEN(sv);
> +	sv = new_sv;
> +    }
>      else {
>  	SvTEMP_off(sv);
>  	(void)SvREFCNT_inc(sv);

You will need a similar fix for vec (LvTYPE == 'v') too.

Perhaps an alternative approach would be for substr and vec in an lvalue
context, to return a new mortal rather than using TARG?

-- 
A walk of a thousand miles begins with a single step...
then continues for another 1,999,999 or so.

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About