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

[perl #7508] exists($_[0]) fails for @_ = (undef) in sub calls

Thread Previous | Thread Next
From:
Father Chrysostomos via RT
Date:
July 2, 2013 20:01
Subject:
[perl #7508] exists($_[0]) fails for @_ = (undef) in sub calls
Message ID:
rt-3.6.HEAD-2552-1372795269-1018.7508-15-0@perl.org
On Sat Jun 04 17:26:18 2005, davem@iabyn.com wrote:
> On Sat, Jun 04, 2005 at 04:46:38PM -0700, Michael G Schwern wrote:
> > On Sat, Jun 04, 2005 at 10:52:20PM -0000, Sebastian wrote:
> > > Test case: perl -le 'sub a { print exists $_[0] } a(undef); a($f =
> undef);'
> > > Problem: Using exists() on @_ does not work as expected with undef
> >
> > This sheds some light on the problem.  They definately contain
> different
> > structures.  Don't know if Devel::Peek simply can't read the former
> @_ magic
> > in element 0 or if there's simply nothing there.
> 
> exists() on an array is just a hack that checks whether the element is
> &PL_sv_undef or some other SV (which may or may not have an undef
> value).
> foo(undef) manages to the set the element to &PL_sv_undef.
> 
> Can't really be fixed short of using some other static SV to mark
> unused
> elements (cf PL_sv_placeholder), but personally I think that's
> throwing
> good money after bad.

Here is another variant of the same bug, that does not use ‘exists’:

$\="\n";
for ($x,undef) {
    print \$_;
    print sub { \$_[0] }->($_);
}

This is the output I get:

SCALAR(0x7fec6402eef0)
SCALAR(0x7fec6402eef0)
SCALAR(0x7fec64003310)
SCALAR(0x7fec6402e668)

Notice how referential identity is preserved when $x is passed, but not
undef.

This also affects undef constants stored in pads under ithreads.

I was going to try and fix this, but IPC::Open3 relies on this bug.  Its
test suite does this:

	open3 undef, $out, undef, $perl, '-le', "print q _# ${handle}_"

and the module itself does this:

    # simulate autovivification of filehandles because
    # it's too ugly to use @_ throughout to make perl do it for us
    # tchrist 5-Mar-00

    unless (eval  {
	$_[0] = gensym unless defined $_[0] && length $_[0];
	$_[1] = gensym unless defined $_[1] && length $_[1];
	1; })
    {
	# must strip crud for croak to add back, or looks ugly
	$@ =~ s/(?<=value attempted) at .*//s;
	croak "$Me: $@";
    }

Instead of croaking on read-only values, shouldn’t it just skip the
$_[0] assignment and move on?

Or: Should IPC::Open3 be fixed to allow the core bug to be fixed, or is
this sufficient evidence that it is too late to fix this bug?

-- 

Father Chrysostomos


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

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