Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.98k stars 560 forks source link

B::NULL is not false #19156

Open leonerd opened 3 years ago

leonerd commented 3 years ago

In C code it's common to walk the child ops of a given optree node with code such as:

OP *kid = o->op_first;
while(kid) {
  ...
  kid = OpSIBLING(kid);
}

The sibling list is terminated by a node having OpSIBLING == NULL.

At the Perl level when walking the optree with B, it represents a NULL pointer not with a Perlish undef but with a reference to a B::NULL object (for reasons I do not follow). This object class ought to have a boolification overload making it appear false, so you could write the same code shape in Perl. It currently does not, meaning you have to

my $kid = $o->first;
while($kid and ref($kid) ne "B::NULL") {
  ...
  $kid = $kid->sibling;
}
ilmari commented 3 years ago

A similar issue applies to (SV*)NULL, which is represented as bless( do{\(my $o = 0)}, 'B::SPECIAL' ). But I'm not sure if there are any APIs where that causes clunkiness similar to (OP*)NULL in the original report.

ilmari commented 3 years ago

One problem with having B::NULL objects boolify to false is that they are also used for undefined scalar variables (but &PL_sv_undef is another B::SPECIAL):

2> B::svref_2object(\undef)
$res[0] = bless( do{\(my $o = 1)}, 'B::SPECIAL' )

3> my $undef
$res[1] = undef

4> B::svref_2object(\$undef)
$res[2] = bless( do{\(my $o = '94761693423424')}, 'B::NULL' )