Skip to content

Use of uninitialized value within @_ in anonymous array ([]) #22884

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

Closed
richlv opened this issue Jan 3, 2025 · 13 comments
Closed

Use of uninitialized value within @_ in anonymous array ([]) #22884

richlv opened this issue Jan 3, 2025 · 13 comments

Comments

@richlv
Copy link

richlv commented Jan 3, 2025

Module: Data::Dumper

Description
Referencing a non-existent hash results in:

Use of uninitialized value in hash element at get_instances-broken-Dumper.pl line 8.
Use of uninitialized value within @_ in anonymous array ([]) at /usr/lib/perl5/5.40.0/x86_64-linux-thread-multi/Data/Dumper.pm line 613.
$VAR1 = undef;

Steps to Reproduce
Original reproduction code:

use strict;
use warnings;

use Data::Dumper;

my %images;
my $instance = {};
print Dumper($images{$instance->{'data'}->{'image-id'}});

Result:

Use of uninitialized value in hash element at get_instances-broken-Dumper.pl line 8.
Use of uninitialized value within [@_](https://mastodon.social/@_) in anonymous array ([]) at /usr/lib/perl5/5.40.0/x86_64-linux-thread-multi/Data/Dumper.pm line 613.
$VAR1 = undef;

This was shortened by Daniel Böhmer to:

$ perl -MData::Dumper -we 'my (%hash1,%hash2); Dumper($hash1{$hash2{key}})'

Result:

Use of uninitialized value $hash2{"key"} in hash element at -e line 1.
Use of uninitialized value within @_ in anonymous array ([]) at /opt/perl5/perlbrew/perls/perl-5.40.0/lib/5.40.0/x86_64-linux-thread-multi/Data/Dumper.pm line 613.

Expected behavior
The warning about "anonymous array" not to be there.

Perl configuration

Summary of my perl5 (revision 5 version 40 subversion 0) configuration:
   
  Platform:
    osname=linux
    osvers=6.9.7-1-default
    archname=x86_64-linux-thread-multi
    uname='reproducible'
    config_args='-ds -e -Dprefix=/usr -Dvendorprefix=/usr -Dinstallusrbinperl -Dusethreads -Di_db -Di_dbm -Di_ndbm -Di_gdbm -Dd_dbm_open -Duseshrplib=true -Doptimize=-O2 -Wall -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type -g -Wall -pipe -Duse64bitint -Dotherlibdirs=/usr/lib/perl5/site_perl -Dinc_version_list=none'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
  Compiler:
    cc='cc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    optimize='-O2 -Wall -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -Werror=return-type -g -Wall -pipe'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong'
    ccversion=''
    gccversion='13.3.0'
    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 =' -L/usr/local/lib64 -fstack-protector-strong'
    libpth=/usr/local/lib /usr/x86_64-suse-linux/lib /usr/lib /usr/lib64 /usr/local/lib64
    libs=-lm -ldl -lcrypt -lpthread
    perllibs=-lm -ldl -lcrypt -lpthread
    libc=/lib64//lib64/libc.so.6
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.39'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.40.0/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC'
    lddlflags='-shared -L/usr/local/lib64 -fstack-protector-strong'


Characteristics of this binary (from libperl): 
  Compile-time options:
    HAS_LONG_DOUBLE
    HAS_STRTOLD
    HAS_TIMES
    MULTIPLICITY
    PERLIO_LAYERS
    PERL_COPY_ON_WRITE
    PERL_DONT_CREATE_GVSV
    PERL_HASH_FUNC_SIPHASH13
    PERL_HASH_USE_SBOX32
    PERL_MALLOC_WRAP
    PERL_OP_PARENT
    PERL_PRESERVE_IVUV
    PERL_USE_SAFE_PUTENV
    USE_64_BIT_ALL
    USE_64_BIT_INT
    USE_ITHREADS
    USE_LARGE_FILES
    USE_LOCALE
    USE_LOCALE_COLLATE
    USE_LOCALE_CTYPE
    USE_LOCALE_NUMERIC
    USE_LOCALE_TIME
    USE_PERLIO
    USE_PERL_ATOF
    USE_REENTRANT_API
    USE_THREAD_SAFE_LOCALE
  Built under linux
  Compiled at Jul  3 2024 07:31:25
  @INC:
    /usr/lib/perl5/site_perl/5.40.0/x86_64-linux-thread-multi
    /usr/lib/perl5/site_perl/5.40.0
    /usr/lib/perl5/vendor_perl/5.40.0/x86_64-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.40.0
    /usr/lib/perl5/5.40.0/x86_64-linux-thread-multi
    /usr/lib/perl5/5.40.0
    /usr/lib/perl5/site_perl
@mauke
Copy link
Contributor

mauke commented Jan 3, 2025

Unrelated to Data::Dumper:

$ perl -we 'my %h; sub { [@_] }->($h{+undef})'
Use of uninitialized value in hash element at -e line 1.
Use of uninitialized value within @_ in anonymous array ([]) at -e line 1.

@jkeenan
Copy link
Contributor

jkeenan commented Jan 5, 2025

Unrelated to Data::Dumper:

$ perl -we 'my %h; sub { [@_] }->($h{+undef})'
Use of uninitialized value in hash element at -e line 1.
Use of uninitialized value within @_ in anonymous array ([]) at -e line 1.

@mauke, am I correct in thinking that this ticket is Not a Bug, hence closable?

@jkeenan jkeenan added Closable? We might be able to close this ticket, but we need to check with the reporter and removed Needs Triage labels Jan 5, 2025
@mauke
Copy link
Contributor

mauke commented Jan 5, 2025

Why do you think it's not a bug?

@jkeenan
Copy link
Contributor

jkeenan commented Jan 5, 2025

Why do you think it's not a bug?

That was simply my interpretation of the fact that you started off your reply with "Unrelated to Data::Dumper." But, given that Data::Dumper itself has warnings enabled, wouldn't we expect that warning?

@mauke
Copy link
Contributor

mauke commented Jan 5, 2025

The first warning, yes. But as the reporter says:

Expected behavior
The warning about "anonymous array" not to be there.

I suspect this is caused by the hash element being in "potential lvalue" context (because it is a subroutine argument). If the hash element doesn't exist yet, it will be created on demand, but only if the subroutine assigns to $_[0] (which is why it cannot be created up front). In this case, the subroutine only reads from $_[0], which somehow triggers another hash lookup using the original key (which is undef). This triggers a duplicate warning, but the warnings machinery gets confused by there being no apparent cause in the code. (An operation like [@foo] should simply copy the array elements, undef or not, without any warnings.) So it blames the "uninitialized value" warning on an element of @_ when the real cause is the hidden undef hash key.

@jkeenan
Copy link
Contributor

jkeenan commented Jan 5, 2025

The first warning, yes. But as the reporter says:

Expected behavior
The warning about "anonymous array" not to be there.

I suspect this is caused by the hash element being in "potential lvalue" context (because it is a subroutine argument). If the hash element doesn't exist yet, it will be created on demand, but only if the subroutine assigns to $_[0] (which is why it cannot be created up front). In this case, the subroutine only reads from $_[0], which somehow triggers another hash lookup using the original key (which is undef). This triggers a duplicate warning, but the warnings machinery gets confused by there being no apparent cause in the code. (An operation like [@foo] should simply copy the array elements, undef or not, without any warnings.) So it blames the "uninitialized value" warning on an element of @_ when the real cause is the hidden undef hash key.

Oooookay ... so what should we do about this. Would documenting the anomaly be sufficient?

@jkeenan jkeenan removed the Closable? We might be able to close this ticket, but we need to check with the reporter label Jan 5, 2025
@jkeenan jkeenan changed the title Data::Dumper: Use of uninitialized value within @_ in anonymous array ([]) Use of uninitialized value within @_ in anonymous array ([]) Jan 5, 2025
@mauke
Copy link
Contributor

mauke commented Jan 5, 2025

Oooookay ... so what should we do about this. Would documenting the anomaly be sufficient?

There is no hash lookup in the visible Perl code, so preferably we wouldn't emit a warning for code that the user didn't write. Not sure how feasible this would be to implement.

@tonycoz
Copy link
Contributor

tonycoz commented Jan 6, 2025

This looks like #22423

@znik3040
Copy link

It does not seem a bug in Data::Dumper. But in discussion is one big mistake:

  1. Original construction:
    my %images; my $instance = {}; Dumper($images{$instance->{'data'}->{'image-id'}});
  2. Shortened (single line) construction:
    my (%hash1,%hash2); Dumper($hash1{$hash2{key}})';

There are completly different construction.
In both examples, datas are empty.

In 2'th example, $hash2{key} returns undef, because there is no key 'key' in the hash.
next, $hash1{undef} returns undef, because %hash1 does not have undef() key. We should not create undef key, because it depends. Undef as a key for hash is converted as 'undef', but if you will use undef , but it is converted to empty string if you will use undef() .
Finally, example 2 is bad on this idea. Bug is reported in construction, not in Data::Dumper .

example in 1'th is more interesting. %images and anonymous hash table pointed by $instance are empty. But look at the construction:
$images{$instance->{'data'}->{'image-id'}}

let's separate key construction:
$instance->{'data'}->{'image-id'}
There is 2 step addresing. First, is $instance->{'data'} . Simple. This should return undef, because key 'data' does not exist.
But look more to right side, construction ->{'image-id'}

In that construction, perl silently fill lost chain element 'data'. It will create second anonymous empty hash, addressed by 'data' key.
Finally after this construction, $instance will be automatically filled by:

say Dumper $nstance;
$VAR1 = {
          'data' => {}
        };

of course, value of returned key $instance->{'data'}->{'image-id'} is undef, because key does not exists.
finally Dumper($images{undef}) is bad construction.

This is not a bug in Data::Dumper module, but in your script. You should look, key or element exists or not, by using exists . It is base for structured data manipulation.

I tested it on This is perl 5, version 28, subversion 1 (v5.28.1) built for x86_64-linux-gnu-thread-multi , but this is not changed by years.

I run this example code, and my result is:

Use of uninitialized value in hash element at ./tt1.pl line 9.
$VAR1 = undef;

Only one difference between my older perl and reported there, is information in printed warning. nothing else.
in my opinion this issue is closable

@tonycoz
Copy link
Contributor

tonycoz commented Feb 16, 2025

The confusing warning seems like a bug to me.

My WIP fix for #22423 also fixes this:

tony@venus:.../git/perl6$ perl -we 'my %h; sub { [@_] }->($h{+undef})'
Use of uninitialized value in hash element at -e line 1.
Use of uninitialized value within @_ in anonymous array ([]) at -e line 1.
tony@venus:.../git/perl6$ ./perl -we 'my %h; sub { [@_] }->($h{+undef})'
Use of uninitialized value in hash element at -e line 1.
tony@venus:.../git/perl6$ perl ../22884.pl 
Use of uninitialized value in hash element at ../22884.pl line 8.
Use of uninitialized value within @_ in anonymous array ([]) at /usr/lib/x86_64-linux-gnu/perl/5.36/Data/Dumper.pm line 606.
$VAR1 = undef;
tony@venus:.../git/perl6$ ./perl -Ilib ../22884.pl 
Use of uninitialized value in hash element at ../22884.pl line 8.
$VAR1 = undef;
tony@venus:.../git/perl6$ git log -n2 --oneline
c46bcabdad (HEAD -> 22423-undef-lvref) Preserve behaviour of allowing an undefined key for tied hash lookups
b97e0893e6 Prevent misleading undefined value warnings if defelem magic

I hadn't realized is only started in 5.34:

tony@venus:.../git/perl6$ ~/perl/5.34.0-dbg/bin/perl ../22884.pl 
Use of uninitialized value in hash element at ../22884.pl line 8.
Use of uninitialized value within @_ in anonymous array ([]) at /home/tony/perl/5.34.0-dbg/lib/5.34.0/x86_64-linux/Data/Dumper.pm line 614.
$VAR1 = undef;
tony@venus:.../git/perl6$ ~/perl/5.32.0-dbg/bin/perl ../22884.pl 
Use of uninitialized value in hash element at ../22884.pl line 8.
$VAR1 = undef;

which leads me to look at what specifically started the extra warning.

@tonycoz
Copy link
Contributor

tonycoz commented Feb 17, 2025

The 5.32 vs 5.34 difference is due to use warnings; being added to Data::Dumper.

@tonycoz
Copy link
Contributor

tonycoz commented Mar 10, 2025

Fixed by a0b9367. 0684569

@tonycoz tonycoz closed this as completed Mar 10, 2025
@richlv
Copy link
Author

richlv commented Mar 11, 2025

Yay, thank you :)

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

5 participants