develooper Front page | perl.perl5.porters | Postings from September 2016

Re: [perl #6997] "Useless use of concatenation" warning nottriggered by multiple concatenations.

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
September 29, 2016 09:18
Subject:
Re: [perl #6997] "Useless use of concatenation" warning nottriggered by multiple concatenations.
Message ID:
20160929091816.GO3193@iabyn.com
On Sat, Jan 16, 2016 at 01:40:08PM -0800, Matthew Horsfall via RT wrote:
> On Mon May 14 21:22:06 2001, pnewton@gmx.de wrote:
> > $ ./perl -w -e '($a,$b)=(42)x2; $a . $b'
> > Useless use of concatenation (.) or string in void context at -e line 1.
> > $ ./perl -w -e '($a,$b,$c)=(42)x3; $a . $b . $c'
> > (nothing)
> > 
> > To me, the second concatenation is also in void context.
> 
> Agreed.
> 
> This seems to stem from some old code that I'm not sure is necessary any more.
> 
> Perl_ck_concat does:
> 
>     if (kid->op_type == OP_CONCAT && !(kid->op_private & OPpTARGET_MY) &&
>             !(kUNOP->op_first->op_flags & OPf_MOD))
>         o->op_flags |= OPf_STACKED;
> 
> But why does it do this?
> 
> Removing Perl_ck_concat makes $a . $b . $c warn properly, and doesn't break the test suite (legit, right?).
> 

It's an optimisation, so I suggest not removing it.

The (($a . $b) . $c) is being compiled as (essentially)

    (($a . $b) .= $c)

i.e. the temporary (padtmp) result of the first concat is just reused and
appended to, rather than using a second temporary and copying both strings
to it.

As an aside, I've occasionally thought that we need an OP_CONCATLIST op,
where rpeep() converts a nested tree of concat ops into a (PUSHMARK, arg,
arg, ...,  CONCATLIST) sequence, where the CONCATLIST op is a bit like
join('', ....) (but more efficient).


-- 
Overhead, without any fuss, the stars were going out.
    -- Arthur C Clarke

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