Skip to content
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

sort{$a<=>$b} fails to sort occasionally #15768

Closed
p5pRT opened this issue Dec 13, 2016 · 14 comments
Closed

sort{$a<=>$b} fails to sort occasionally #15768

p5pRT opened this issue Dec 13, 2016 · 14 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 13, 2016

Migrated from rt.perl.org#130335 (status was 'resolved')

Searchable as RT130335$

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2016

From tails.saito@gmail.com

This is a bug report for perl from tails.saito@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.22.2.

Greetings,

sort{$a<=>$b} fails to sort a list of strings numerically in some cases.
Here is an example.

Code​:
@​in = (
  "0",
  "20000000000000001",
  "20000000000000000" );
@​result = sort {$a<=>$b} @​in;
print join "\n", @​result;

Output​:
0
20000000000000001
20000000000000000

However, if I use {0;$a<=>$b} instead of {$a<=>$b},
I get a correct result.

Code​:
@​in = (
  "0",
  "20000000000000001",
  "20000000000000000" );
@​result = sort {0;$a<=>$b} @​in;
print join "\n", @​result;

Output​:
0
20000000000000000
20000000000000001

I confirmed the above matter happens with​:
perl v5.22.2 cygwin-thread-multi-64int; and
perl v5.16.3 on CentOS.

I noticed the above matter does NOT happen with​:
Debian perl-5.14.2-9.

Thank you for your attention.


Flags​:
  category=core
  severity=medium


Site configuration information for perl 5.22.2​:

Configured by ASSI at Sat Apr 30 15​:59​:30 CEST 2016.

Summary of my perl5 (revision 5 version 22 subversion 2) configuration​:

  Platform​:
  osname=cygwin, osvers=2.5.1(0.29753), archname=cygwin-thread-multi-64int
  uname='cygwin_nt-6.3-wow cygwin 2.5.1(0.29753) 2016-04-21 22​:12
i686 cygwin '
  config_args='-des -Dprefix=/usr -Dmksymlinks
-Darchname=i686-cygwin-threads-64int -Dlibperl=cygperl5_22.dll
-Dcc=gcc -Dld=g++ -Accflags=-ggdb -O2 -pipe
-Wimplicit-function-declaration
-fdebug-prefix-map=/mnt/share/maint/perl.x86/build=/usr/src/debug/perl-5.22.2-1
-fdebug-prefix-map=/mnt/share/maint/perl.x86/src/perl-5.22.2=/usr/src/debug/perl-5.22.2-1
-fwrapv'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=define, usemultiplicity=define
  use64bitint=define, use64bitall=undef, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='gcc', ccflags ='-DPERL_USE_SAFE_PUTENV -D_GNU_SOURCE
-U__STRICT_ANSI__ -ggdb -O2 -pipe -Wimplicit-function-declaration
-fdebug-prefix-map=/mnt/share/maint/perl.x86/build=/usr/src/debug/perl-5.22.2-1
-fdebug-prefix-map=/mnt/share/maint/perl.x86/src/perl-5.22.2=/usr/src/debug/perl-5.22.2-1
-fwrapv -fno-strict-aliasing -fstack-protector-strong
-D_FORTIFY_SOURCE=2',
  optimize='-O3',
  cppflags='-DPERL_USE_SAFE_PUTENV -D_GNU_SOURCE -U__STRICT_ANSI__
-ggdb -O2 -pipe -Wimplicit-function-declaration
-fdebug-prefix-map=/mnt/share/maint/perl.x86/build=/usr/src/debug/perl-5.22.2-1
-fdebug-prefix-map=/mnt/share/maint/perl.x86/src/perl-5.22.2=/usr/src/debug/perl-5.22.2-1
-fwrapv -fno-strict-aliasing -fstack-protector-strong'
  ccversion='', gccversion='5.3.0', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8,
byteorder=12345678, doublekind=3
  d_longlong=define, longlongsize=8, d_longdbl=define,
longdblsize=12, longdblkind=3
  ivtype='long long', ivsize=8, nvtype='double', nvsize=8,
Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='g++', ldflags =' -Wl,--enable-auto-import
-Wl,--export-all-symbols -Wl,--enable-auto-image-base
-fstack-protector-strong'
  libpth=/usr/lib
  libs=-lpthread -lgdbm -ldb -ldl -lcrypt -lgdbm_compat
  perllibs=-lpthread -ldl -lcrypt
  libc=/usr/lib/libcygwin.a, so=dll, useshrplib=true, libperl=cygperl5_22.dll
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ', lddlflags=' --shared -Wl,--enable-auto-import
-Wl,--export-all-symbols -Wl,--enable-auto-image-base
-fstack-protector-strong'


@​INC for perl 5.22.2​:
  /usr/lib/perl5/site_perl/5.22/i686-cygwin-threads-64int
  /usr/lib/perl5/site_perl/5.22
  /usr/lib/perl5/vendor_perl/5.22/i686-cygwin-threads-64int
  /usr/lib/perl5/vendor_perl/5.22
  /usr/lib/perl5/5.22/i686-cygwin-threads-64int
  /usr/lib/perl5/5.22
  .


Environment for perl 5.22.2​:
  HOME=/home/user
  LANG=ja_JP.utf-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2016

From @jkeenan

On Tue, 13 Dec 2016 03​:33​:59 GMT, tails.saito@​gmail.com wrote​:

This is a bug report for perl from tails.saito@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.22.2.

Greetings,

sort{$a<=>$b} fails to sort a list of strings numerically in some
cases.
Here is an example.

Code​:
@​in = (
"0",
"20000000000000001",
"20000000000000000" );
@​result = sort {$a<=>$b} @​in;
print join "\n", @​result;

Output​:
0
20000000000000001
20000000000000000

However, if I use {0;$a<=>$b} instead of {$a<=>$b},
I get a correct result.

Code​:
@​in = (
"0",
"20000000000000001",
"20000000000000000" );
@​result = sort {0;$a<=>$b} @​in;
print join "\n", @​result;

Output​:
0
20000000000000000
20000000000000001

I confirmed the above matter happens with​:
perl v5.22.2 cygwin-thread-multi-64int; and
perl v5.16.3 on CentOS.

I noticed the above matter does NOT happen with​:
Debian perl-5.14.2-9.

Thank you for your attention.

Here's my understanding of the problem.

When I saw these two strings​:

#####
"20000000000000001",
"20000000000000000"
#####

... my suspicions were aroused. I wondered if, when perl performed its string-to-number conversion, the resulting number was "too big".

In 'perldoc perlnumber' (for perl-5.24.0), we have​:

#####
Perl can internally represent numbers in 3 different ways​: as native
integers, as native floating point numbers, and as decimal strings.
...
On typical hardware, floating point values can store numbers with up
to 53 binary digits.... In decimal representation this is close
to 16 decimal digits.
#####

On my machine, at least, your strings, when converted to numbers have 17 decimal digits and at least 53 binary digits.

#####
$ perl -E 'say (2**52 - 1); say (2**52); say (2**53); say 20000000000000001;'
4503599627370495
4.5035996273705e+15
9.00719925474099e+15
20000000000000001
#####

Now, as the attachment demonstrates, it appears that the numeric comparison ("spaceship") operator, '<=>', can *by itself* handle comparisons of numbers in that range okay. But when used inside a sort block, it fails with big numbers.

Here's the output of the attachment when run on my machine​:

#####
$ prove -v 130335-sort-string-numerically.t
130335-sort-string-numerically.t ..
ok 1 - strings holding numbers sorted as strings (no numbers in bigint range)
ok 2 - strings holding numbers sorted as numbers (returning numbers) (no numbers in bigint range)
ok 3 - strings holding numbers sorted as strings (some numbers in bigint range)
not ok 4 - strings holding numbers sorted as numbers (returning numbers) (some numbers in bigint range)

# Failed test 'strings holding numbers sorted as numbers (returning numbers) (some numbers in bigint range)'
# at 130335-sort-string-numerically.t line 93.
# Structures begin differing at​:
# $got->[6] = '20000000000000002'
# $expected->[6] = '20000000000000001'
ok 5 - strings holding numbers numerically compared​: -1
ok 6 - strings holding numbers numerically compared​: 0
ok 7 - strings holding numbers numerically compared​: 1
ok 8 - strings holding big numbers numerically compared​: -1
ok 9 - strings holding big numbers numerically compared​: 0
ok 10 - strings holding big numbers numerically compared​: 1
1..10
# Looks like you failed 1 test of 10.
Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/10 subtests

Test Summary Report


130335-sort-string-numerically.t (Wstat​: 256 Tests​: 10 Failed​: 1)
  Failed test​: 4
  Non-zero exit status​: 1
Files=1, Tests=10, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.02 cusr 0.00 csys = 0.04 CPU)
Result​: FAIL
#####

I do not know enough about the built-in 'sort' function to say why this is so.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2016

From @jkeenan

# perl
use strict;
use warnings;
use Test​::More;

my @​intstrings;
my @​bigintstrings;
my @​moreintstrings;
my @​numstrings;
my (@​sorteds, @​numsorteds);
my $exp;

@​intstrings = (
  '300002',
  '300000',
  '300001',
);
@​bigintstrings = (
  '20000000000000002',
  '20000000000000001',
  '30000000000000000',
);
@​moreintstrings = (
  '1999999',
  '0',
  '1999998',
);
@​numstrings = (
  @​intstrings,
  @​moreintstrings,
);
@​sorteds = sort @​numstrings;
$exp = [
  '0',
  '1999998',
  '1999999',
  '300000',
  '300001',
  '300002',
];
is_deeply([ @​sorteds ], $exp,
  "strings holding numbers sorted as strings (no numbers in bigint range)");

@​numsorteds = sort { $a <=> $b } @​numstrings;
$exp = [
  0,
  300000,
  300001,
  300002,
  1999998,
  1999999,
];
is_deeply([ @​numsorteds ], $exp,
  "strings holding numbers sorted as numbers (returning numbers) (no numbers in bigint range)");

#####

@​numstrings = (
  @​intstrings,
  @​bigintstrings,
  @​moreintstrings,
);

@​sorteds = sort @​numstrings;
$exp = [
  '0',
  '1999998',
  '1999999',
  '20000000000000001',
  '20000000000000002',
  '300000',
  '30000000000000000',
  '300001',
  '300002',
];
is_deeply([ @​sorteds ], $exp,
  "strings holding numbers sorted as strings (some numbers in bigint range)");

@​numsorteds = sort { $a <=> $b } @​numstrings;
$exp = [
  0,
  300000,
  300001,
  300002,
  1999998,
  1999999,
  20000000000000001,
  20000000000000002,
  30000000000000000,
];
is_deeply([ @​numsorteds ], $exp,
  "strings holding numbers sorted as numbers (returning numbers) (some numbers in bigint range)");

is( ('300000' <=> '300001'), -1, "strings holding numbers numerically compared​: -1");
is( ('300000' <=> '300000'), 0, "strings holding numbers numerically compared​: 0");
is( ('300002' <=> '300001'), 1, "strings holding numbers numerically compared​: 1");

is( ('20000000000000001' <=> '20000000000000002'), -1,
  "strings holding big numbers numerically compared​: -1");
is( ('20000000000000001' <=> '20000000000000001'), 0,
  "strings holding big numbers numerically compared​: 0");
is( ('20000000000000002' <=> '20000000000000001'), 1,
  "strings holding big numbers numerically compared​: 1");

done_testing();

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2016

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2016

From @tonycoz

On Tue, 13 Dec 2016 14​:38​:05 -0800, jkeenan wrote​:

On Tue, 13 Dec 2016 03​:33​:59 GMT, tails.saito@​gmail.com wrote​:

This is a bug report for perl from tails.saito@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.22.2.

Greetings,

sort{$a<=>$b} fails to sort a list of strings numerically in some
cases.
Here is an example.

Code​:
@​in = (
"0",
"20000000000000001",
"20000000000000000" );
@​result = sort {$a<=>$b} @​in;
print join "\n", @​result;

Output​:
0
20000000000000001
20000000000000000

However, if I use {0;$a<=>$b} instead of {$a<=>$b},
I get a correct result.

Code​:
@​in = (
"0",
"20000000000000001",
"20000000000000000" );
@​result = sort {0;$a<=>$b} @​in;
print join "\n", @​result;

Output​:
0
20000000000000000
20000000000000001

I confirmed the above matter happens with​:
perl v5.22.2 cygwin-thread-multi-64int; and
perl v5.16.3 on CentOS.

I noticed the above matter does NOT happen with​:
Debian perl-5.14.2-9.

Thank you for your attention.

Here's my understanding of the problem.

When I saw these two strings​:

#####
"20000000000000001",
"20000000000000000"
#####

... my suspicions were aroused. I wondered if, when perl performed
its string-to-number conversion, the resulting number was "too big".

In 'perldoc perlnumber' (for perl-5.24.0), we have​:

#####
Perl can internally represent numbers in 3 different ways​: as native
integers, as native floating point numbers, and as decimal strings.
...
On typical hardware, floating point values can store numbers with up
to 53 binary digits.... In decimal representation this is close
to 16 decimal digits.
#####

You've got the right idea here.

It looks like the issue is in S_sv_ncmp in pp_sort.c

When the compiler sees code like​:

  @​x = sort { $a <=> $b } @​y

it marks the sort op to perform the comparison internally rather than using the <=> op.

Unfortunately that internal comparison is doing a simple SvNV() <=> SvNV() comparison rather than the more careful comparison that the real <=> op does.

Working on a patch.

Tony

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2016

From @hvds

On Mon, 12 Dec 2016 19​:33​:59 -0800, tails.saito@​gmail.com wrote​:

sort{$a<=>$b} fails to sort a list of strings numerically in some cases.
Here is an example.

Code​:
@​in = (
"0",
"20000000000000001",
"20000000000000000" );
@​result = sort {$a<=>$b} @​in;
print join "\n", @​result;

Output​:
0
20000000000000001
20000000000000000

There is an optimization that detects specific common sort subs such as { $a <=> $b } and substitutes a faster equivalent written in C; in this case that uses the function S_sv_ncmp() in pp_sort.c.

A quick glance at that shows that it is using its internally defined macro SvNSIV() to extract the numeric value, which always prefers an NV (floating point value) to an IV (integer value); this appears to be the opposite way round to the implementation of the spaceship operator (Perl_do_ncmp() in pp.c), but I'm not sure why.

In any case it does explain the results you get - your NV clearly doesn't have enough precision to distinguish the two values - and also why your workaround (dodging the optimization by inserting "0;" in the sort sub) avoids the problem.

It's been working this way since 2005; before that it used NV only. That suggests it might be tricky to change. I'd class it as clearly a bug though.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Dec 13, 2016

From zefram@fysh.org

James E Keenan via RT wrote​:

I do not know enough about the built-in 'sort' function to say why this is so.

The main built-in numeric comparison for sorting, S_sv_ncmp() in
pp_sort.c, reduces each value to an NV. This is quite unlike the full
<=> op, Perl_do_ncmp() in pp.c, which tries to work in IVs if possible.
sort does make some attempt to use an IV comparison instead, but only if
*all* the values being sorted are sufficiently integral. Examination of
the flags on the sorted values shows that it is indeed falling back on
NV comparison in this case.

Bizarrely, it seems that the "0" element is the one that's not
sufficiently integral. Looking at how the flags are set for a range of
strings, it's something like only setting the IOK flag for values that
are outside the range where the NV format can represent all integers.
That is, it's only judging a value to be sufficiently integral if the
NV format won't work, rather than if the IV format will work. The logic
is buried in Perl_sv_2nv_flags() in sv.c.

The logic for whether IV comparisons are OK on a specific value for
sorting is broken. sv_2nv_flags() doesn't set IOK in the circumstances
that the sorting code expects. I'm not clear whether this is a bug in
sv_2nv_flags() or in pp_sort()'s use of it.

But regardless of that per-value logic, pp_sort() errs in falling back
to an NV-only comparison when it can't use IV comparison. It needs
to do a full numeric comparison, basically calling Perl_do_ncmp().
Perhaps it could use NV-only comparison as an optimisation only when it
establishes that all the values are adequately represented in NV form,
but there's no flag by which it could judge that.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2016

From @tonycoz

On Tue, 13 Dec 2016 15​:13​:22 -0800, tonyc wrote​:

Working on a patch.

Attached.

Tony

@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2016

From @tonycoz

0001-perl-130335-fix-numeric-comparison-for-sort-s-built-.patch
From f1ec0e92b0c10828bda3762df4706fa4d01c6573 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 14 Dec 2016 14:24:08 +1100
Subject: (perl #130335) fix numeric comparison for sort's built-in compare

For non-'use integer' this would always compare as NVs, but with
64-bit integers and non-long doubles, integers can have more
significant digits, making the sort <=> replacement less precise
than the <=> operator.

Use the same code to perform the comparison that <=> does, which
happens to be handily broken out into Perl_do_ncmp().
---
 pp_sort.c              | 12 ++++--------
 t/lib/warnings/9uninit |  2 +-
 t/op/sort.t            | 15 ++++++++++++++-
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/pp_sort.c b/pp_sort.c
index 68e65f9..4ffe224 100644
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1888,20 +1888,16 @@ S_sortcv_xsub(pTHX_ SV *const a, SV *const b)
 static I32
 S_sv_ncmp(pTHX_ SV *const a, SV *const b)
 {
-    const NV nv1 = SvNSIV(a);
-    const NV nv2 = SvNSIV(b);
+    I32 cmp = do_ncmp(a, b);
 
     PERL_ARGS_ASSERT_SV_NCMP;
 
-#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
-    if (Perl_isnan(nv1) || Perl_isnan(nv2)) {
-#else
-    if (nv1 != nv1 || nv2 != nv2) {
-#endif
+    if (cmp == 2) {
 	if (ckWARN(WARN_UNINITIALIZED)) report_uninit(NULL);
 	return 0;
     }
-    return nv1 < nv2 ? -1 : nv1 > nv2 ? 1 : 0;
+
+    return cmp;
 }
 
 static I32
diff --git a/t/lib/warnings/9uninit b/t/lib/warnings/9uninit
index c8b843f..77a93ce 100644
--- a/t/lib/warnings/9uninit
+++ b/t/lib/warnings/9uninit
@@ -651,8 +651,8 @@ Use of uninitialized value $m1 in sort at - line 6.
 Use of uninitialized value $g1 in sort at - line 6.
 Use of uninitialized value $m1 in sort at - line 7.
 Use of uninitialized value $g1 in sort at - line 7.
-Use of uninitialized value $m1 in sort at - line 7.
 Use of uninitialized value $g1 in sort at - line 7.
+Use of uninitialized value $m1 in sort at - line 7.
 Use of uninitialized value $a in subtraction (-) at - line 8.
 Use of uninitialized value $b in subtraction (-) at - line 8.
 Use of uninitialized value $m1 in sort at - line 9.
diff --git a/t/op/sort.t b/t/op/sort.t
index cd1c6eb..96fad1c 100644
--- a/t/op/sort.t
+++ b/t/op/sort.t
@@ -7,7 +7,7 @@ BEGIN {
     set_up_inc('../lib');
 }
 use warnings;
-plan(tests => 196);
+plan(tests => 197);
 
 # these shouldn't hang
 {
@@ -1147,3 +1147,16 @@ pass "no crash when sort block deletes *a and *b";
     @a = sort { *a = sub { 1 }; $a <=> $b } 0 .. 1;
     ok(a(), "*a wasn't localized inadvertantly");
 }
+
+SKIP:
+{
+    eval { require Config; 1 }
+      or skip "Cannot load Config", 1;
+    $Config::Config{ivsize} == 8
+      or skip "this test can only fail with 64-bit integers", 1;
+    # sort's built-in numeric comparison wasn't careful enough in a world
+    # of integers with more significant digits than NVs
+    my @in = ( "0", "20000000000000001", "20000000000000000" );
+    my @out = sort { $a <=> $b } @in;
+    is($out[1], "20000000000000000", "check sort order");
+}
-- 
2.1.4

@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2016

From @jkeenan

On Wed, 14 Dec 2016 03​:25​:24 GMT, tonyc wrote​:

On Tue, 13 Dec 2016 15​:13​:22 -0800, tonyc wrote​:

Working on a patch.

Attached.

Tony

Created local branch with your patch. PASS on my test program. Please apply unless Hugo or Zefram finds something amiss in the C code. Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2016

From takeshi@ix.netcom.com

I saw a similar issue.
When I coded;
my $a = undef;
before sort line, the sort doesn't work, however, without 'my' statement, it works.
Probably it might be a bug.

On Mon, 12 Dec 2016 19​:33​:59 -0800, tails.saito@​gmail.com wrote​:

This is a bug report for perl from tails.saito@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.22.2.

Greetings,

sort{$a<=>$b} fails to sort a list of strings numerically in some
cases.
Here is an example.

Code​:
@​in = (
"0",
"20000000000000001",
"20000000000000000" );
@​result = sort {$a<=>$b} @​in;
print join "\n", @​result;

Output​:
0
20000000000000001
20000000000000000

However, if I use {0;$a<=>$b} instead of {$a<=>$b},
I get a correct result.

Code​:
@​in = (
"0",
"20000000000000001",
"20000000000000000" );
@​result = sort {0;$a<=>$b} @​in;
print join "\n", @​result;

Output​:
0
20000000000000000
20000000000000001

I confirmed the above matter happens with​:
perl v5.22.2 cygwin-thread-multi-64int; and
perl v5.16.3 on CentOS.

I noticed the above matter does NOT happen with​:
Debian perl-5.14.2-9.

Thank you for your attention.
---
Flags​:
category=core
severity=medium
---
Site configuration information for perl 5.22.2​:

Configured by ASSI at Sat Apr 30 15​:59​:30 CEST 2016.

Summary of my perl5 (revision 5 version 22 subversion 2)
configuration​:

Platform​:
osname=cygwin, osvers=2.5.1(0.29753), archname=cygwin-thread-multi-
64int
uname='cygwin_nt-6.3-wow cygwin 2.5.1(0.29753) 2016-04-21 22​:12
i686 cygwin '
config_args='-des -Dprefix=/usr -Dmksymlinks
-Darchname=i686-cygwin-threads-64int -Dlibperl=cygperl5_22.dll
-Dcc=gcc -Dld=g++ -Accflags=-ggdb -O2 -pipe
-Wimplicit-function-declaration
-fdebug-prefix-
map=/mnt/share/maint/perl.x86/build=/usr/src/debug/perl-5.22.2-1
-fdebug-prefix-map=/mnt/share/maint/perl.x86/src/perl-
5.22.2=/usr/src/debug/perl-5.22.2-1
-fwrapv'
hint=recommended, useposix=true, d_sigaction=define
useithreads=define, usemultiplicity=define
use64bitint=define, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler​:
cc='gcc', ccflags ='-DPERL_USE_SAFE_PUTENV -D_GNU_SOURCE
-U__STRICT_ANSI__ -ggdb -O2 -pipe -Wimplicit-function-declaration
-fdebug-prefix-
map=/mnt/share/maint/perl.x86/build=/usr/src/debug/perl-5.22.2-1
-fdebug-prefix-map=/mnt/share/maint/perl.x86/src/perl-
5.22.2=/usr/src/debug/perl-5.22.2-1
-fwrapv -fno-strict-aliasing -fstack-protector-strong
-D_FORTIFY_SOURCE=2',
optimize='-O3',
cppflags='-DPERL_USE_SAFE_PUTENV -D_GNU_SOURCE -U__STRICT_ANSI__
-ggdb -O2 -pipe -Wimplicit-function-declaration
-fdebug-prefix-
map=/mnt/share/maint/perl.x86/build=/usr/src/debug/perl-5.22.2-1
-fdebug-prefix-map=/mnt/share/maint/perl.x86/src/perl-
5.22.2=/usr/src/debug/perl-5.22.2-1
-fwrapv -fno-strict-aliasing -fstack-protector-strong'
ccversion='', gccversion='5.3.0', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8,
byteorder=12345678, doublekind=3
d_longlong=define, longlongsize=8, d_longdbl=define,
longdblsize=12, longdblkind=3
ivtype='long long', ivsize=8, nvtype='double', nvsize=8,
Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries​:
ld='g++', ldflags =' -Wl,--enable-auto-import
-Wl,--export-all-symbols -Wl,--enable-auto-image-base
-fstack-protector-strong'
libpth=/usr/lib
libs=-lpthread -lgdbm -ldb -ldl -lcrypt -lgdbm_compat
perllibs=-lpthread -ldl -lcrypt
libc=/usr/lib/libcygwin.a, so=dll, useshrplib=true,
libperl=cygperl5_22.dll
gnulibc_version=''
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags=' --shared -Wl,--enable-auto-import
-Wl,--export-all-symbols -Wl,--enable-auto-image-base
-fstack-protector-strong'

---
@​INC for perl 5.22.2​:
/usr/lib/perl5/site_perl/5.22/i686-cygwin-threads-64int
/usr/lib/perl5/site_perl/5.22
/usr/lib/perl5/vendor_perl/5.22/i686-cygwin-threads-64int
/usr/lib/perl5/vendor_perl/5.22
/usr/lib/perl5/5.22/i686-cygwin-threads-64int
/usr/lib/perl5/5.22
.

---
Environment for perl 5.22.2​:
HOME=/home/user
LANG=ja_JP.utf-8
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PERL_BADLANG (unset)
SHELL=/bin/bash

--
TakeshiKitahara

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2016

From tails.saito@gmail.com

Hi,

2016-12-16 14​:16 GMT+09​:00 Takeshi Kitahara via RT <perlbug-followup@​perl.org>​:

I saw a similar issue.
When I coded;
my $a = undef;
before sort line, the sort doesn't work, however, without 'my' statement, it works.
Probably it might be a bug.

Where "my $a" is declared, you can use $​::a (or "our $a" in a package)
to refer to the global variable which contains the element to be
sorted,

@​in = (3,1,4,1,5,9,2);
my $a = undef;
@​result = sort { our $a <=> our $b } @​in;

I guess this is not a bug because we should not lose the access to the
lexical variable (my $a) even in a sort sub.

@p5pRT
Copy link
Author

p5pRT commented Dec 23, 2016

From @jkeenan

On Wed, 14 Dec 2016 12​:52​:55 GMT, jkeenan wrote​:

On Wed, 14 Dec 2016 03​:25​:24 GMT, tonyc wrote​:

On Tue, 13 Dec 2016 15​:13​:22 -0800, tonyc wrote​:

Working on a patch.

Attached.

Tony

Created local branch with your patch. PASS on my test program.
Please apply unless Hugo or Zefram finds something amiss in the C
code. Thank you very much.

No objection was raised, so I applied Tony's patch in commit 427fbfe. Resolving ticket.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 23, 2016

@jkeenan - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant