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

[perl #118691] Perl crash on usage of index [-1] for array in subroutine call

Thread Previous | Thread Next
From:
James E Keenan via RT
Date:
June 29, 2013 15:07
Subject:
[perl #118691] Perl crash on usage of index [-1] for array in subroutine call
Message ID:
rt-3.6.HEAD-2552-1372518372-1074.118691-15-0@perl.org
On Sat Jun 29 06:54:53 2013, wolf-dietrich_moeller@t-online.de wrote:
> Hi,
> the following behaviour of Perl looks like a bug to me:
> 
> In the test program below, the third and fourth call to the subroutine
> should behave equal, i.e. the fourth call should not result in a crash of
> Perl with the following message:
> "Modification of non-creatable array value attempted, subscript -1 at
<PATH
> TO PERL PROGRAM> line 17."
> 
> Reason for my assumption is that the  " // undef" in the first call
and the
> third call to "func" should be superfluous, as the non-existing array
> element should return "undef" anyhow. Thus the third call and the fourth
> call should behave identical.
> 
> Test program:
> ########################################
> # Test program to show crash of Perl in the fourth call to 'sub func'
> # Such crash seems to happen only when the index is negative and the array
> element does not exist.
> # For positive indices no crash, even if the array element does not exist.
> use strict;
> sub func ($) { my $val = shift; print $val // 'undef'," in sub func\n" }
> my @array;
> my $x = $array[0];
> my $y = $array[-1];
> print '@array[0,-1] : ',join(' ',map $_ // 'undef',$x,$y)," in main\n";
> print '($array[0] // undef) :',"\n";
> func ($array[0] // undef);
> print '($array[0]) :',"\n";
> func ($array[0]);
> print '($array[-1] // undef) :',"\n";
> func ($array[-1] // undef);
> print '($array[-1]) :',"\n";
> func ($array[-1]);
> ###########################################
> 
> The output of the test program is:
> @array[0,-1] : undef undef in main
> ($array[0] // undef) :
> undef in sub func
> ($array[0]) :
> undef in sub func
> ($array[-1] // undef) :
> undef in sub func
> ($array[-1]) :
> Modification of non-creatable array value attempted, subscript -1 at <PATH
> TO PERL PROGRAM> line 17.
> 

I don't think this is a bug in Perl.  In fact, it's a feature
specifically documented in 'perldoc perldiag'"

#####
Modification of non-creatable array value attempted, %s

(F) You tried to make an array value spring into existence, and the
subscript was probably negative, even counting from end of the array
backwards.
#####

To explain this, I would like to strip your demonstration code of
superfluous aspects.  Among other things, there is absolutely no reason
for a prototype on your subroutine.  Since you're working in Perl
5.16.3, you have the 'say' function available to you, and I'll use that
to reduce the number of keystrokes in the code.

#####
use strict;
use warnings;
use feature 'say';

my @array;
func ($array[0] // undef);
func ($array[0]);
func ($array[-1] // undef);
func ($array[-1]);

sub func { my $val = shift; say $val // 'undef'; }
#####

Perl's '//' operator tests the defined-ness of the left-hand side of the
operator, returns that value if it is defined, but returns the
right-hand side if the left-hand is not defined.

In your third call to 'func()', the '//' operator imposes a context on
the values to its left and to its right.  In this context, the left-hand
value, $array[-1], is found to be not defined, so whatever is on the
right-hand side of '//' is returned.  It so happens that what is on the
right-hand side is the undefined value.  So that is what is passed to
func(), and func() handles it appropriately by printing the string
'undef' to STDOUT.

Your fourth call is not equivalent to your third call.  There's no '//'
operator imposing a context on $array[-1].  Perl looks at that variable
directly and notes that it runs afoul of the error condition described
above.  You're asking for $array[-1] to spring to life.  I'm sure that
there are others who can explain better than I can why we treat that as
a fatal error -- but fatal it is nonetheless.

> PS.
> Sorry I did not use the recommended tools for version reporting, as
nowadays
> I only have access to Windows environment with ActiveState Perl windows
> binary.

For reporting the version of Perl in which you are experiencing a
problem, all you need to do is to include the output of 'perl -V' in
your email to 'perlbug@perl.org'.

Thank you very much.
Jim Keenan

---
via perlbug:  queue: perl5 status: new
https://rt.perl.org:443/rt3/Ticket/Display.html?id=118691

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