I've got the following script running on Perl 5.10.1:
#!/usr/bin/perl
use strict;
use warnings;
foreach( my $x =0 ; $x < 1; $x++) { # Line 5
print_line(); # Line 6
}
sub print_line {
print "Function call from line: " . [caller(0)]->[2] . "\n";
}
Despite the call to the subroutine coming from line 6, the script outputs the line number of the start of the C-style for statement:
Function call from line: 5
What's really weird is if I throw a random statement into one of the blank line in the C-style for loop, caller
returns the correct line number:
#!/usr/bin/perl
use strict;
use warnings;
foreach( my $x =0 ; $x < 1; $x++) {
my $x = 3;
print_line(); # Line 7
}
sub print_line {
print "Function call from line: " . [caller(0)]->[2] . "\n";
}
The above script correctly outputs:
Function call from line: 7
Is this some kind of bug or is there something I can do to get caller
to accurately report the line number?
I think potentially it is a bug, because the same behavior doesn't occur if you replace
foreach (my $x = 0 ; $x < 1 ; $x++) {
with
foreach my $x (0 .. 0) {
I don't understand exactly what's happening, but by comparing the optrees of the two different versions, I think that a nextstate
op is getting improperly optimized out. My version has
<;> nextstate(main 4 lineno.pl:11) v:*,&,x*,x&,x$,$ ->8
as the left sibling of the entersub
op that calls print_line
, while yours has
<0> ex-nextstate v ->8
which has been taken out of the flow of execution.
It wouldn't hurt to write this up as a perlbug.
$ perl -MO=Concise a.pl
j <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 6 a.pl:5) v:*,&,{,x*,x&,x$,$ ->3
5 <2> sassign vKS/2 ->6
3 <$> const[IV 0] s ->4
4 <0> padsv[$x:3,5] sRM*/LVINTRO ->5
6 <0> unstack v* ->7
i <2> leaveloop vK/2 ->j
7 <{> enterloop(next->b last->i redo->8) v ->e
- <1> null vK/1 ->i
h <|> and(other->8) vK/1 ->i
g <2> lt sK/2 ->h
e <0> padsv[$x:3,5] s ->f
f <$> const[IV 1] s ->g
- <@> lineseq vK ->-
- <@> scope vK ->b <---
- <0> ex-nextstate v ->8 <---
a <1> entersub[t5] vKS/TARG,2 ->b
- <1> ex-list K ->a
8 <0> pushmark s ->9
- <1> ex-rv2cv sK/2 ->-
9 <#> gv[*print_line] s/EARLYCV ->a
c <1> preinc[t2] vK/1 ->d
b <0> padsv[$x:3,5] sRM ->c
d <0> unstack v ->e
a.pl syntax OK
There's some optimization going on. The scope
was deemed unnecessary and optimized away. (Notice the "-
" meaning it's never reached.)
But at the same time, that removed the nextstate
op, which is what sets the line number for warnings and for caller
.
So, it's a bug that results from an improper optimization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With