develooper Front page | perl.perl5.porters | Postings from April 2017

[perl #131155] string-to-number coercion caching broken by locale

From:
Zefram
Date:
April 15, 2017 00:44
Subject:
[perl #131155] string-to-number coercion caching broken by locale
Message ID:
rt-4.0.24-21440-1492217057-1673.131155-75-0@perl.org
# New Ticket Created by  Zefram 
# Please include the string:  [perl #131155]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/Ticket/Display.html?id=131155 >



This is a bug report for perl from zefram@fysh.org,
generated with the help of perlbug 1.40 running under perl 5.25.11.


-----------------------------------------------------------------
[Please describe your issue here]

Riffing off the discussion in [perl #130801] of the locale dependence of
number-to-string coercion, and hence why we no longer cache that coercion
in the scalar, I had a look at the converse string-to-number coercion,
and found a bug:

$ LANG=de_DE perl -lwe '$a = "1,50"; { use locale; print 0+$a; } print 0+$a'
1,5
1.5
$ LANG=de_DE perl -lwe '$a = "1,50"; print 0+$a'
Argument "1,50" isn't numeric in addition (+) at -e line 1.
1

Observe that the string-to-number coercion is affected by locale,
accepting comma as a decimal separator iff the locale uses comma in
that way.  (Not shown: dot is accepted as a decimal separator regardless
of locale.)  The result of the coercion is cached in the scalar, and
subsequent numeric use of the scalar returns the cached value without
recomputing the coercion.  Given the locale dependence, this caching
is in principle wrong, because it means that coercions performed under
different locale settings aren't getting their locale-specific results.
That can be seen above, with the non-locale coercion producing a different
result depending on whether a locale-using coercion was earlier performed.

But actually I think the locale dependence here is a mistake.  Unlike the
locale dependence of number-to-string coercion, the locale dependence of
this operation doesn't exist in any form in old perls.	It appeared from
nowhere in perl 5.19.8, presumably in the same edit that (intentionally)
changed the form of the locale control for number-to-string coercion.
We also have some semantic reliance on the caching for reasons other than
this effect on the value yielded: we only warn once about a non-numeric
value, and we're somewhat open about the influence of an argument having
been used in numeric context on the bitwise operators.

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
    category=core
    severity=low
---
Site configuration information for perl 5.25.11:

Configured by zefram at Mon Mar 20 22:41:51 GMT 2017.

Summary of my perl5 (revision 5 version 25 subversion 11) configuration:
   
  Platform:
    osname=linux
    osvers=3.16.0-4-amd64
    archname=x86_64-linux-thread-multi
    uname='linux barba.rous.org 3.16.0-4-amd64 #1 smp debian 3.16.7-ckt11-1+deb8u6 (2015-11-09) x86_64 gnulinux '
    config_args='-des -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.25.11-i64-f52 -Duselargefiles -Dusethreads -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dusedevel -Uversiononly -Ui_db'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
    bincompat5005=undef
  Compiler:
    cc='cc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
    optimize='-O2'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='4.9.2'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=3
    ivtype='long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='off_t'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries:
    ld='cc'
    ldflags =' -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
    libs=-lpthread -lnsl -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.19.so
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.19'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E -Wl,-rpath,/home/zefram/usr/perl/perl_install/perl-5.25.11-i64-f52/lib/5.25.11/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC'
    lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'


---
@INC for perl 5.25.11:
    /home/zefram/usr/perl/perl_install/perl-5.25.11-i64-f52/lib/site_perl/5.25.11/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.25.11-i64-f52/lib/site_perl/5.25.11
    /home/zefram/usr/perl/perl_install/perl-5.25.11-i64-f52/lib/5.25.11/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.25.11-i64-f52/lib/5.25.11

---
Environment for perl 5.25.11:
    HOME=/home/zefram
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/zefram/usr/perl/perl_install/perl-5.25.11-i64-f52/bin:/home/zefram/usr/perl/util:/home/zefram/pub/x86_64-unknown-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/bin:/usr/local/bin:/usr/games
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About