New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subroutine doesn't create elements. #5310
Comments
From @AbigailCreated by @Abigailman perlsub states: Any arguments passed in show up in the array "@_". There- Now, consider this program: #!/usr/bin/perl -w use strict; sub mysub; $, = " "; # 0 1 2 3 print map {defined $_ ? $_ : "^^"} @arr; sub mysub { If we run this, we get: That is, $arr [4] isn't 0.50 after the function mysub was called, bleadperl gives the same behaviour. Abigail Perl Info
|
From @schwernOn Fri, Apr 05, 2002 at 02:50:30PM -0000, abigail@foad.org wrote:
Likely related to this feature: $ perl -wle '@a = ("foo ", "bar ", "woof ", undef); $a[3] is not defined, but it exists. $a[4] exists but is not defined. Internally, $a[3] would contain an SV with the value of undef and but since this feature was added in 5.6.0 (or there abouts) and your Devel::Peek seems to be confused by @arr. It doesn't see past element SV = RV(0x10138350) at 0x1012ef44 -- Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/ |
From @AbigailOn Fri, Apr 05, 2002 at 10:51:44AM -0500, Michael G Schwern wrote:
I think you mean that $a [4] neither exists, nor is defined. But that's exactly my point. The documentation says: If an argument is an array or hash element which DID NOT EXIST when The element doesn't exist (as exists shows), is modified, yet isn't Abigail |
From @schwernOn Fri, Apr 05, 2002 at 06:26:17PM +0200, abigail@foad.org wrote:
Yes, I'm not disagreeing with you (despite my brain-o, it's early for -- Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/ |
From @tamiasOn Fri, Apr 05, 2002 at 02:50:30PM -0000, abigail@foad.org wrote:
I believe you are misreading the documentation. It's referring to a #!perl -w sub mysub1 { sub mysub2 { mysub1($arr[0]); print "$arr[0]\n"; mysub2($arr[0]); print "$arr[0]\n"; 1 Note that the subs are being called with "an array ... element which did Keep in mind that arrays passed to subroutines are flattened, so: @arr = (0, 1); is equivalent to: @arr = (0, 1); mysub has no notion that it was called with @arr as an argument. The Ronald |
From @tamiasOn Fri, Apr 05, 2002 at 11:58:58AM -0500, Ronald J Kimball wrote:
On second thought, I think I misread your bug report. Apologies. I see Ronald |
From [Unknown Contact. See original ticket]On Fri, 5 Apr 2002 12:05:40 -0500, rjk@linguist.Thayer.dartmouth.edu
On the third hand, if $arr[4] is &PL_sv_undef, then assigning to $_[4] On the fourth hand, it does mean that the documentation is incorrect (or Cheers, |
From @schwernOn Fri, Apr 05, 2002 at 09:26:41PM +0200, Philip Newton wrote:
$arr[4] containing &PL_sv_undef is correct. @_ aliasing is definately doing something Evil and probably not going
Don't document bugs as features. Then you can never fix it. -- Michael G. Schwern <schwern@pobox.com> http://www.pobox.com/~schwern/ |
From @AbigailOn Fri, Apr 05, 2002 at 09:26:41PM +0200, Philip Newton wrote:
Changing the documentation means you are extending the language. You'd have a hard time to explain why the following doesn't #!/usr/bin/perl -w use strict; sub mysub; $, = " "; my @arr1 = ("cent", "nickel", "dime", undef); my @arr2 = @arr1; mysub @arr1; sub mysub { __END__ This will print: 0.01 0.05 0.1 0.25 ^^^ 1 Abigail |
From @mjdominus
Unfortunately, it does. print exists($a[3]) ? "1\n" : "0\n"; The output is 0 I still think this was a bad idea, for exactly the reason you cite, |
From renee.baecker@smart-websolutions.deThe auto-vivification doesn't create SV's at all: rbaecker@www-devel-rbaecker ~/perl510/bugs $ cat 8910.pl use strict; my @b = (undef,undef,undef,undef); print "\n\n"; my @c; print "\n"; sub test { SV = RV(0x8189260) at 0x815de10 -- Renée Bäcker XING: http://www.xing.com/profile/Renee_Baecker |
From @davidnicolOn 6/11/08, Renée Bäcker <renee.baecker@smart-websolutions.de> wrote:
|
From @dcollinsnIn blead, it throws an error now. Porting/bisect.pl --start v5.10.0 --end v5.22.0 --target miniperl -Dcc='ccache gcc-6' -- ./miniperl ../8910.pl ce0d59f is the first bad commit [perl #7508] Use NULL for nonexistent array elems This commit fixes bug #7508 and provides the groundwork for fixing Elements of @_ are aliased to the arguments, so that \$_[0] within &PL_sv_undef (the global read-only undef scalar returned by the This also causes other problems with constants under ithreads This commit changes the internals to use a null pointer to represent a This requires that Storable be changed to account for it. Also, :100644 100644 b15f6ff7b60ea28323b7bba85b7bdaae7132782f aae70bf8acfcce9fe5f71143d6039efeb8c8e2a9 M av.c |
From @dcollinsnI probably should mention, it segfaults in that commit, it doesn't segfault in blead. Here's what it does now: dcollins@nightshade64:~/toolchain/perl$ ./perl ../8910.pl |
From @cpansproutOn Mon Jul 04 18:02:26 2016, dcollinsn@gmail.com wrote:
The solution is probably to have S_pushav in pp_hot.c push a defelem rather than &PL_sv_undef if it is in flattening lvalue context. We have to check for nulls anyway. (I have been told that defelems are too slow. This may not be the best solution.) -- Father Chrysostomos |
From zefram@fysh.orgFixed in commit 6661956. Fix caused -zefram |
From @dur-randirOn Tue, 16 Jan 2018 11:19:20 -0800, zefram@fysh.org wrote:
I'd very cautiously monitor effects of this commit - as it can result in very hard to detect but measurable fall down in execution speed and increased memory consumption. And that's not mentioning new bugs. Off the top of my head, I was able to produce the following: 5.26.0 blead |
From @cpansproutOn Tue, 16 Jan 2018 16:22:44 -0800, randir wrote:
Not only that, it also breaks use of exists and delete on arrays. I think it should be reverted. -- Father Chrysostomos |
From @xenuOn Tue, 16 Jan 2018 17:49:18 -0800
It's a bit off-topic, but what's the point of exists and delete on |
From zefram@fysh.orgFather Chrysostomos via RT wrote:
Not really. delete() and exists() on array elements still work as
We should not compromise the coherent consecutive-indices model of arrays -zefram |
From zefram@fysh.orgTomasz Konojacki wrote:
It was an attempt to make arrays serve two distinct purposes -zefram |
From @cpansproutOn Tue, 16 Jan 2018 18:20:42 -0800, zefram@fysh.org wrote:
It escaped that fate on the ground that there are regular users of the feature who would have to tweak thousands of lines of code if it were removed. (I still disagree with the ‘strongly discouraged’ label.)
If a pure rvalue operation starts having observable side effects, then that is a bug. Introducing a new bug for the sake of fixing an existing one is not a reasonable compromise, considering that Perl favours backward-compatibility. You also have not responded to the localization bug that Mr. Aleynikov brought up. Flagging the op in \(@a) is easy enough to do. Surely there aren’t too many lvalue cases that are not currently flagged as lvalues?
-- Father Chrysostomos |
From zefram@fysh.orgFather Chrysostomos via RT wrote:
Is it a bug? It's a change in behaviour, but the semantics of "local" $ perl5.27.7 -lwe '$#a = 3; print I'm more inclined to call this one a bug than what my edit introduced, I see you've edited the code in commit $ perl5.27.8 -lwe '$#a = 3; print exists($a[0])||0; my @b = @a; print exists($a[0])||0' I'm not a fan of the deferred-element approach. Firstly, it means that But even if it worked, it means that the deferred elements get created -zefram |
From @cpansproutOn Sat, 20 Jan 2018 14:44:17 -0800, zefram@fysh.org wrote:
The existing behaviour is longstanding. Yes, it could be called a bug. One could argue it either way, so I don’t think it should be changed without a good reason. I have a good reason, which is off-topic for this ticket, but please let this wait until after 5.28, because my as-yet unwritten proposal changes more than just this, for the sake of consistency, and may be controversial.
Thank you for pointing that out. I have rectified it in commit 0f3591f.
Hmm, does that mean that support for tied arrays slows down all @a access once $#a has been mentioned? Maybe we should fix that. (Again, off-topic for this ticket.)
I have a fix in mind that will make it a one-time penalty and fix #132729, at least for elephants within the array. Namely, we could store the deferred elements in the array and change the way the magic works. I think that can be done for 5.28. -- Father Chrysostomos |
From @dur-randirOn Sat, 20 Jan 2018 14:44:17 -0800, zefram@fysh.org wrote:
Ten years ago this was considered a bug: commit 4ad10a0 On scope end, delete localized array elements that should not exist anymore, so that the array recovers its previous length. Honour EXISTS and DELETE for tied arrays. Has any implications changed since then? |
From @cpansproutOn Sun, 21 Jan 2018 16:24:55 -0800, sprout wrote:
Please review the ‘Nonelem’ patch in the sprout/nonelem branch. It currently fixes #132729 only for the cases covered by this ticket (S_pushav), but it could be extended to other uses of deferred elements. However, it would only be a partial fix for #132729, not applying to elephants beyond the end of the array. Fixing *that* would be harder, but doable (but probably too intrusive for 5.28). It is worth applying a partial fix? The commit does not yet include tests for #132729 or for the memory leaks it fixes. I also have not had time yet to benchmark it. -- Father Chrysostomos |
From @cpansproutOn Sun, 21 Jan 2018 21:59:24 -0800, sprout wrote:
Replying to myself, I think it is worth it, because most Perl programmers probably do not realize that arrays can have holes in them. I have applied my fix in the branch merged as 2a05854.
The branch includes that.
I know my method is primitive, but it should not matter considering the stark difference: $ time ./miniperl -e '$#a++; for (1..5000000) { map 1, @a }' real 0m7.991s $ time ./newminiperl -e '$#a++; for (1..5000000) { map 1, @a }' real 0m4.503s The first is blead before the merge (with my previous, inefficient defelem fix). The second is after the merge. -- Father Chrysostomos |
@cpansprout - Status changed from 'open' to 'pending release' |
From @dur-randirHere's some comparison between a97021b (representing point right before this change) and 8c11620 (representing blead): % perf stat -r 5 -e instructions,branches,branch-misses,cache-misses ./miniperl_a97021b9d2 -e 'sub foo{} $a[5] = 1; foo(@a) for (1..100_000_000)' Performance counter stats for './miniperl_a97021b9d2 -e sub foo{} $a[5] = 1; foo(@a) for (1..100_000_000)' (5 runs): 68,408,669,959 instructions ( +- 0.00% ) 7.886012337 seconds time elapsed ( +- 0.45% ) % perf stat -r 5 -e instructions,branches,branch-misses,cache-misses ./miniperl_8c11620dca -e 'sub foo{} $a[5] = 1; foo(@a) for (1..100_000_000)' Performance counter stats for './miniperl_8c11620dca -e sub foo{} $a[5] = 1; foo(@a) for (1..100_000_000)' (5 runs): 68,208,661,954 instructions ( +- 0.00% ) 7.753697959 seconds time elapsed ( +- 0.43% ) Calling subs with empty slots takes now ~4% more branches. % perf stat -r 5 -e instructions,branches,branch-misses,cache-misses ./miniperl_a97021b9d2 -e 'sub foo{} @a=(1)x5; foo(@a) for (1..100_000_000)' Performance counter stats for './miniperl_a97021b9d2 -e sub foo{} @a=(1)x5; foo(@a) for (1..100_000_000)' (5 runs): 66,508,170,242 instructions ( +- 0.00% ) 7.426998822 seconds time elapsed ( +- 0.09% ) % perf stat -r 5 -e instructions,branches,branch-misses,cache-misses ./miniperl_8c11620dca -e 'sub foo{} @a=(1)x5; foo(@a) for (1..100_000_000)' Performance counter stats for './miniperl_8c11620dca -e sub foo{} @a=(1)x5; foo(@a) for (1..100_000_000)' (5 runs): 66,308,249,789 instructions ( +- 0.00% ) 7.480210740 seconds time elapsed ( +- 0.26% ) Calling subs with dense array is, again, taking 4% more branches. Blead is chosen here to demonstrate that nothing fundamentally changed after recent patches from Father Chrysostomos, the main hit was done by 6661956 (though instructions improved a bit, but I didn't pinpoint that to specific commit/change): % perf stat -r 5 -e instructions,branches,branch-misses,cache-misses ./miniperl_6661956a23 -e 'sub foo{} $a[5] = 1; foo(@a) for (1..100_000_000)' Performance counter stats for './miniperl_6661956a23 -e sub foo{} $a[5] = 1; foo(@a) for (1..100_000_000)' (5 runs): 68,708,344,437 instructions ( +- 0.00% ) 7.620128855 seconds time elapsed ( +- 0.52% ) |
From @khwilliamsonThank you for filing this report. You have helped make Perl better. With the release yesterday of Perl 5.28.0, this and 185 other issues have been Perl 5.28.0 may be downloaded via: If you find that the problem persists, feel free to reopen this ticket. |
@khwilliamson - Status changed from 'pending release' to 'resolved' |
Migrated from rt.perl.org#8910 (status was 'resolved')
Searchable as RT8910$
The text was updated successfully, but these errors were encountered: