Closed p5pRT closed 20 years ago
The following script causes a Bus error in 5.6.0; it fails silently in 5.004_05
----
use File::Find; sub wanted { next unless /i/; #should be return
}
find (\&wanted\, '.') ---
Dbx reports the following backtrace:
=>[1] Perl_av_pop(0x3a3a7761\, 0x0\, 0x2\, 0x11ca68\, 0x7\, 0x111b38)\, at 0x7def4 [2] Perl_pp_pop(0x118800\, 0x118400\, 0x11c018\, 0x3a3a7761\, 0x11c014\, 0x3a3a7761)\, at 0xa56e4 [3] Perl_runops_standard(0x1187e0\, 0xffbe6b74\, 0xff2338f0\, 0x0\, 0xffbe6dd8\, 0x0)\, at 0x7f7b0 [4] S_run_body(0x1\, 0x118400\, 0x113400\, 0x118000\, 0x0\, 0x119870)\, at 0x2abb0 [5] perl_run(0x119004\, 0x27734\, 0x2\, 0xffbe6c94\, 0x0\, 0x2)\, at 0x2a8a0 [6] main(0x0\, 0x117b80\, 0xffbe6c94\, 0x10c000\, 0x0\, 0x0)\, at 0x276f4
Jim Carey (lists.p5p):
use File::Find; sub wanted { next unless /i/; #should be return } find (\&wanted\, '.')
Fixed in perl-current; close that bug!
simon@brecon.co.uk (Simon Cozens) wrote
Fixed in perl-current; close that bug!
It's certainly changed in perl-current\, but I'm not sure it's entirely fixed.
Running his example under perl-current with -wd\, I see
DB\<2> c 4
main::wanted(-:4): next unless /i/; #should be return
DB\<3> T
. = main::wanted called from file `lib/File/Find.pm' line 432
. = File::Find::_find_dir(ref(HASH)\, .\, 30) called from file `lib/File/Find.pm' line 342
. = File::Find::_find_opt(ref(HASH)\, .) called from file `lib/File/Find.pm' line 719
. = File::Find::find(ref(CODE)\, .) called from file `-' line 11
DB\<3> s
Exiting subroutine via next at - line 4.
Exiting subroutine via next at - line 4.
File::Find::_find_dir(lib/File/Find.pm:511):
511: while ( defined ($SE = pop @Stack) ) {
DB\<3> w 427
424
425: while (defined $SE) {
426: unless ($bydepth) {
427: $dir= $p_dir;
428: $name= $dir_name;
429: $_= ($no_chdir ? $dir_name : $dir_rel );
430 # prune may happen here
431: $prune= 0;
432: &$wanted_callback;
433: next if $prune;
DB\<4>
[ Exercise for the reader - why does the error message happen twice? ]
So the subroutine being exited is being called from line 432. And the smallest surrounding loop to that is the while() on line 425. But the "next" in fact takes us to line 511. Hmmm...
And it also occurs to me that things like File::Find doing callbacks should protect themselves against wild loop control statements. See the attached patch.
Perhaps Perl should *define* loop controls which exit subroutines as equivalent to "return;" ?
Mike Guy
From: "M.J.T. Guy" \mjtg@​cus\.cam\.ac\.uk
Perhaps Perl should *define* loop controls which exit subroutines as equivalent to "return;" ?
Why? What's wrong with just return?
"Bryan C. Warnock" \bwarnock@​gtemail\.net wrote
From: "M.J.T. Guy" \mjtg@​cus\.cam\.ac\.uk
Perhaps Perl should *define* loop controls which exit subroutines as equivalent to "return;" ?
Why? What's wrong with just return?
You're asking the question the wrong way round. People *shouldn't* use 'next' etc in this circumstance. But they may do\, and this can confuse the logic of callers\, such as File::Find. The suggested change would obviate the need for precautionary coding such as in my patch.
And since it may not have been obvious\, the suggestion wasn't really serious. It'd never get past the Backward Compatibility Police.
But having to defend callbacks like that is a pain.
Mike Guy
Perhaps Perl should *define* loop controls which exit subroutines as equivalent to "return;" ?
Why? What's wrong with just return?
You're asking the question the wrong way round. People *shouldn't* use 'next' etc in this circumstance. But they may do\, and this can confuse the logic of callers\, such as File::Find. The suggested change would obviate the need for precautionary coding such as in my patch.
Sorry. Bad parsing.... :-) I was inserting an implicit "new" between define and loop.
On Tue\, Jul 18\, 2000 at 11:30:16AM +0100\, M.J.T. Guy wrote:
And it also occurs to me that things like File::Find doing callbacks should protect themselves against wild loop control statements. See the attached patch.
Which has been now applied.
Perhaps Perl should *define* loop controls which exit subroutines as equivalent to "return;" ?
A very good question (and something to define in more detail for Perl 6\, certainly).
Jarkko Hietaniemi \jhi@​iki\.fi wrote
On Tue\, Jul 18\, 2000 at 11:30:16AM +0100\, M.J.T. Guy wrote:
Perhaps Perl should *define* loop controls which exit subroutines as equivalent to "return;" ?
A very good question (and something to define in more detail for Perl 6\, certainly).
As I remarked in a followup message\, that wasn't intended entirely seriously\, for compatibility reasons.
And if it's to be changed in Perl 6\, the Right Thing would be to make it an error\, so that loop controls are defined lexically and can be entirely bound at compile time.
Mike Guy
Migrated from rt.perl.org#3536 (status was 'resolved')
Searchable as RT3536$