develooper Front page | perl.perl5.porters | Postings from March 2013

Re: Infinite loop in for (@a) { push @a, $_ }

Thread Previous | Thread Next
From:
Brad Gilbert
Date:
March 19, 2013 15:51
Subject:
Re: Infinite loop in for (@a) { push @a, $_ }
Message ID:
CAD2L-T3UWr+zg7ZLrTec2BqOh9SHCyMsMrgKB4ysrOum60x0Tw@mail.gmail.com
On Tue, Mar 19, 2013 at 6:57 AM, demerphq <demerphq@gmail.com> wrote:
> On 19 March 2013 12:43, Nicholas Clark <nick@ccl4.org> wrote:
>> On Tue, Mar 19, 2013 at 12:18:11PM +0100, demerphq wrote:
>>> This code is an infinite loop.
>>>
>>>    my @a = ("A".."D");
>>>    for (@a) {
>>>        say;
>>>        push @a, $_;
>>>    }
>>>
>>> I think this is a regression as compared to how it would have worked
>>> when for (@a) operated on the stack and put a copy of @a on the stack.
>>
>> I discovered that 5.004 has the current behaviour, whereas 5.001 does not,
>> so I ran this:
>
> Thanks. That is what I suspected.
>
>> bisect.pl --force-manifest --target miniperl --end perl-5.004 -le 'alarm 1; my @a = ("A".."D"); for (@a) { print; push @a, $_; } '
>>
>> and it says that the behaviour changed in 1996:
>>
>> commit 5f05dabc4054964aa3b10f44f8468547f051cdf8
>> Author: Perl 5 Porters <perl5-porters@africa.nicoh.com>
>> Date:   Thu Dec 19 16:44:00 1996 +1200
>>
>>     [inseparable changes from patch from perl5.003_11 to perl5.003_12]
>>
>>
>> with a massive list of changes, and it's not clear which was responsible for
>> this.
>>
>>> Does anyone agree? I would expect this to be the same (more or less) as:
>>>
>>> push @a, @a;
>>>
>>> And not an infinite loop.
>>
>> I'd like it not to be an infinite loop, but I'm not sure what the cost of
>> fixing it would be. If I understand this one correctly, it's not actually
>> a "stack isn't reference counted" bug. It's an optimisation peeping through.
>
> Seems to me we just* have to remember the size of the array when we
> start the for() loop and only iterate to that size. That would
> preserve the behavior of 5.001.
>
> IMO If people want to mess around with code like this they should
> write it using a while loop.
>
> Yves
> * Im assuming this is minor enough to deserve a "just". ;-)
>

I don't think we can "fix" it.

If we used a copy of the list, or kept track of the last index, or
really anything that would keep track of the old state; then this
wouldn't work:

$ perl -E'@a=10;for(@a){push @a, $_-1 if $_} say join ",", @a'

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