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 ClarkeThread Previous | Thread Next