Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Use of uninitialized value: when don't you get that?

Reply
Thread Tools

Use of uninitialized value: when don't you get that?

 
 
Tim McDaniel
Guest
Posts: n/a
 
      12-15-2011
I like to have "use strict" and "use warnings" (actually, "-w" on my
scripts). I'm now wondering: when can you use an undefined value and
not get the "Use of uninitialized value" warning. Experimentally, I
don't get the warning with

my $x = undef;
my $y = undef;
if ($y) { ... }
if (! $y) { ... }
if ($y && ! $y) { ... }
if (exists $x->{notdef}) { ... }
if (defined $x->{notdef}) { ... }
if ($x->{notdef}) { ... }
# and none of those autovivify it.

(at least under Perl 5.008008, which is what my workplace uses).

Is there a more complete listing of conditions that cause the warning
and/or those that do not? I consider "using the value" to be an
insufficient explantion, because I consider "if ($y)" to be a use of
the value. "Using the value with an operator" covers cases like "+"
and "." and "eq", but it doesn't work for me because "&&" is an
operator too.

--
Tim McDaniel, http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Lucien Coffe
Guest
Posts: n/a
 
      12-16-2011
Tim McDaniel wrote¬*:

> I like to have "use strict" and "use warnings" (actually, "-w" on my
> scripts).


I think the "use warnings" way is the recommended way. It is scoped to
the file/package, and is clearer.

> I'm now wondering: when can you use an undefined value and
> not get the "Use of uninitialized value" warning. Experimentally, I
> don't get the warning with
>
> my $x = undef;
> my $y = undef;
> if ($y) { ... }
> if (! $y) { ... }
> if ($y && ! $y) { ... }
> if (exists $x->{notdef}) { ... }
> if (defined $x->{notdef}) { ... }
> if ($x->{notdef}) { ... }
> # and none of those autovivify it.
>
> (at least under Perl 5.008008, which is what my workplace uses).
>
> Is there a more complete listing of conditions that cause the warning
> and/or those that do not? I consider "using the value" to be an
> insufficient explantion, because I consider "if ($y)" to be a use of the
> value. "Using the value with an operator" covers cases like "+" and "."
> and "eq", but it doesn't work for me because "&&" is an operator too.


Put it that way : *undef* can be true or false; In list context it is
true, in all scalar contexts it is false. So testing it is not a problem.

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

my $x = undef;
print 1,"\n" if( [ $x ] ); # true
print 2,"\n" if( $x ); # false
print 3,"\n" if( $x++ ); # false

$x = undef;
print 4,"\n" if( ++$x ); # true

$x = undef;
print 5,"\n" if ref $x; # false
print 6,"\n" if( $x->{foo} ); # true
print 7,"\n" if ref $x; # now true, ref $x = HASH

$x = undef;
print 8,"\n" if( "$x" ); # w uninitialized
print 9,"\n" if( $x == 1 ); # w uninitialized


Output from the diagnostics pragma :

(W uninitialized) An undefined value was used as if it were already
defined. It was interpreted as a "" or a 0, but maybe it was a mistake.
To suppress this warning assign a defined value to your variables.

So if you use undef explicitly as a string or as a numeric value, you get
the warning. Hope this helps.
 
Reply With Quote
 
 
 
 
Lucien Coffe
Guest
Posts: n/a
 
      12-16-2011
Lucien Coffe wrote¬*:

> So if you use undef explicitly as a string or as a numeric value, you
> get the warning.


* If you use it explicitly as a string, or if you compare it as a
numerical value.

> Hope this helps.

 
Reply With Quote
 
Lucien Coffe
Guest
Posts: n/a
 
      12-16-2011
Lucien Coffe wrote¬*:

> Lucien Coffe wrote¬*:
>
>> So if you use undef explicitly as a string or as a numeric value, you
>> get the warning.

>
> * If you use it explicitly as a string, or if you compare it as a
> numerical value.
>
>> Hope this helps.


Bumping again.

$x = undef;
print 10,"\n" if( $x+1 ); # w uninitialized

undef++ is undef, ++undef is 1, undef+1 triggers the warning because you
try to interpret undef to it's numerical value to use the + operator.
Someone correct me if I'm wrong.
 
Reply With Quote
 
Tim McDaniel
Guest
Posts: n/a
 
      12-16-2011
In article <jcf0j0$7e7$(E-Mail Removed)>,
Lucien Coffe <(E-Mail Removed)> wrote:
>Tim McDaniel wrote¬*:
>
>> I like to have "use strict" and "use warnings" (actually, "-w" on
>> my scripts).

>
>I think the "use warnings" way is the recommended way. It is scoped
>to the file/package, and is clearer.


Quite so, quite so. I was thinking of the scripts that I've done for
myself, where there's just one file and I'm invoking it as a command.
(I started with Perl 4.036, I think: I'm pretty sure "use warnings"
didn't exist; I don't remember whether "my" even existed, and I
suspect not.)

--
Tim McDaniel, (E-Mail Removed)
 
Reply With Quote
 
Tim McDaniel
Guest
Posts: n/a
 
      12-16-2011
In article <jcf0j0$7e7$(E-Mail Removed)>,
Lucien Coffe <(E-Mail Removed)> wrote:
>Put it that way : *undef* can be true or false; In list context it is
>true, in all scalar contexts it is false.


As I understand it, a boolean context is not a list context, and if
you use undef in a list context, it's put into a list of one element,
which evaluates as true regardless of what that element is.

My understanding is that there is really no undef in a list context:
if you use it in a list context, it is put into a list of one element,
and a list of one element evaluates as true in a boolean context
regardless of what that element is.

>my $x = undef;
>print 1,"\n" if( [ $x ] ); # true


That's testing [...], not undef or lists.

print 1.1,"\n" if( [ ] );

prints 1.1. [...] generates a reference to a list, and a reference to
a list evaluates as true regardless of what the elements are or even,
apparently, whether there are even any elements.

>print 6,"\n" if( $x->{foo} ); # true


False in 5.014002 on NetBSD, 5.008008 on something, and I would be
astonished if it were true anywhere.

>print 7,"\n" if ref $x; # now true, ref $x = HASH


That's true.


Looking further at "man perldiag":

Use of uninitialized value%s

(W uninitialized) An undefined value was used as if it were
already defined. It was interpreted as a "" or a 0, but maybe it
was a mistake. ...

I'm thinking that the first sentence is somewhat imprecise or unclear.
I think the second sentence is the condition: "Use of uninitialized
value" occurs if and only if you use an undef value with an operator
that requires numeric operands (like +, *, ==) or string operands
(like ., printf "%s", split), and not otherwise.

But I'd like to hear from someone authoritative, like someone who
knows how to navigate the source for "perl".

--
Tim McDaniel, (E-Mail Removed)
 
Reply With Quote
 
Rainer Weikusat
Guest
Posts: n/a
 
      12-16-2011
Lucien Coffe <(E-Mail Removed)> writes:

[...]


> Put it that way : *undef* can be true or false; In list context it is
> true, in all scalar contexts it is false.


This is wrong. Invoking a subroutine returning undef in list context
effectivelty causes that to return a list containing a single element
whose value is 'the undefined value'. If this list is assigned to an
array and the array then evaluated in scalar context, the result will
be the number 1 which is regarded as true:

[rw@sapphire]~ $perl -de 0

Loading DB routines from perl5db.pl version 1.32
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main:-e:1): 0
DB<1> sub axtmoerder { return undef; }

DB<2> @a = axtmoerder

DB<3> p scalar(@a)
1
DB<4> p $a[0] || 3
3

[...]

> Output from the diagnostics pragma :
>
> (W uninitialized) An undefined value was used as if it were already
> defined. It was interpreted as a "" or a 0, but maybe it was a mistake.
> To suppress this warning assign a defined value to your variables.


I really think 'we' need another warning whose diagnostics output
should roughly be like this:

An addition operator was used. This was interpreted as an
addition but maybe it was a mistake. To suppress this warning,
add the comment # I mean it !!1 to the corresponding line of
the code.
 
Reply With Quote
 
Tim McDaniel
Guest
Posts: n/a
 
      12-16-2011
In article <jcdo8q$doi$(E-Mail Removed)>,
Tim McDaniel <(E-Mail Removed)> wrote:
>Is there a more complete listing of conditions that cause the warning
>and/or those that do not?


I hit on the right search terms (if only I knew what they were).
http://www.perlmonks.org/?node_id=862 by ambrus, from 2005, points to
perlsyn. The current version says

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~

Declarations

The only things you need to declare in Perl are report formats and
subroutines (and sometimes not even subroutines). A variable holds
the undefined value ("undef") until it has been assigned a defined
value, which is anything other than "undef". When used as a number,
"undef" is treated as 0; when used as a string, it is treated as the
empty string, ""; and when used as a reference that isn't being
assigned to, it is treated as an error. If you enable warnings,
you'll be notified of an uninitialized value whenever you treat
"undef" as a string or a number. Well, usually. Boolean contexts,
such as:

my $a;
if ($a) {}

are exempt from warnings (because they care about truth rather than
definedness). Operators such as "++", "--", "+=", "-=", and ".=",
that operate on undefined left values such as:

my $a;
$a++;

are also always exempt from such warnings.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~

I would put it as: A Boolean context is a scalar context, but it does
not convert values to be either string or a number. Therefore, undef
in a boolean context evaluates as false without producing a
uninitialized warning.

Also, "when used as a reference that isn't being assigned to, it is
treated as an error" does not appear to be accurate.

$x = undef;
if (exists $x->{notdef}) {
print "Huh?\n";
}
printf "after bad ref #3 [%s] [%d] [%s]\n", ref $x,
scalar keys %{$x}, join(',', keys %{$x});

produces only

after bad ref #3 [HASH] [0] []

That is, it doesn't create a something->{notdef} element, but it does
assign $x a reference to a new hash, and there's no error or warning.
I need to go read up on autovivification.

--
Tim McDaniel, (E-Mail Removed)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"defined $r_libs->{$name} " triggers warning "Use of uninitialized value" Liang Perl 2 08-11-2004 07:00 AM
Use of uninitialized value in concatenation smartins68 Perl 1 06-09-2004 05:46 AM
Re: Use of uninitialized value in concatenation (.) or string Error Sukhbir Dhillon Perl 1 04-05-2004 02:31 AM
Use of uninitialized value in concatenation (.) at register.pl line 38, <STDIN> line 10. G Kannan Perl 1 10-11-2003 11:58 AM
why do I see - Use of uninitialized value in undef operator ... Sunil Perl Misc 3 10-06-2003 08:11 AM



Advertisments