Spurious "Use of uninitialized value" with -w, redux

S

Sam Denton

OK, my first post had a bug, but it's a real problem, honest.

Here's my (fixed!) code:

+208 chomp ($fsmount);
+209 $fsmount .= ' ';
+210
+211 print "*** fsmount = \"$fsmount\"";
+212 print ", empty" if $fsmount eq "";
+213 print ", undef" unless defined($fsmount);
+214 print " ***\n";
+215
+216 # if ( $fsmount =~ m=^/= ) {
+217 # $fsmount =~ s/:.*$//;
+218 my $firstchar = substr($fsmount,0,1);
+219 if ( $firstchar eq '/' ) {
+220 $fsmount =~ s/:.*//;

When I run this code with '-w', here's what I see:

# perl unix_replica.pl
*** fsmount = " " ***
Use of uninitialized value in pattern match (m//) at unix_replica.pl
line 218.
*** fsmount = "/: " ***
*** fsmount = " dev = /dev/hd4 " ***
Use of uninitialized value in pattern match (m//) at unix_replica.pl
line 218.
*** fsmount = " vol = "root" " ***
Use of uninitialized value in pattern match (m//) at unix_replica.pl
line 218.

Line 209 guarantees that there's at least one character in $fsmount,
so the 'substr($fsmount,0,1)' should always return one character
string. Everything works just fine without the '-w' option. Any ideas?
 
L

Lukas Mai

Sam Denton schrob:
OK, my first post had a bug, but it's a real problem, honest.
Here's my (fixed!) code:
+208 chomp ($fsmount);
+209 $fsmount .= ' ';
+210
+211 print "*** fsmount = \"$fsmount\"";
+212 print ", empty" if $fsmount eq "";
+213 print ", undef" unless defined($fsmount);
+214 print " ***\n";
+215
+216 # if ( $fsmount =~ m=^/= ) {
+217 # $fsmount =~ s/:.*$//;
+218 my $firstchar = substr($fsmount,0,1);
+219 if ( $firstchar eq '/' ) {
+220 $fsmount =~ s/:.*//;
When I run this code with '-w', here's what I see:
# perl unix_replica.pl
*** fsmount = " " ***
Use of uninitialized value in pattern match (m//) at unix_replica.pl
line 218.

That's weird because line 218 is `my $firstchar = substr($fsmount,0,1)'.
In fact, I don't see any m// in your code (except for the comment in
line 216).

Your code and your error messages don't agree.

HTH, Lukas
 
J

Jon Ericson

OK, my first post had a bug, but it's a real problem, honest.

Here's my (fixed!) code:

+208 chomp ($fsmount);
+209 $fsmount .= ' ';
+210
+211 print "*** fsmount = \"$fsmount\"";
+212 print ", empty" if $fsmount eq "";
+213 print ", undef" unless defined($fsmount);
+214 print " ***\n";
+215
+216 # if ( $fsmount =~ m=^/= ) {
+217 # $fsmount =~ s/:.*$//;
+218 my $firstchar = substr($fsmount,0,1);
+219 if ( $firstchar eq '/' ) {
+220 $fsmount =~ s/:.*//;

When I run this code with '-w', here's what I see:

# perl unix_replica.pl
*** fsmount = " " ***
Use of uninitialized value in pattern match (m//) at unix_replica.pl
line 218.
*** fsmount = "/: " ***
*** fsmount = " dev = /dev/hd4 " ***
Use of uninitialized value in pattern match (m//) at unix_replica.pl
line 218.
*** fsmount = " vol = "root" " ***
Use of uninitialized value in pattern match (m//) at unix_replica.pl
line 218.

Line 209 guarantees that there's at least one character in $fsmount,
so the 'substr($fsmount,0,1)' should always return one character
string. Everything works just fine without the '-w' option. Any ideas?

I think there's something you aren't telling us. :) I don't see a
pattern match on line 218. If the substr were the location of the
error, I'd expect a different message:

$ perl -we 'my $f = substr(undef,0,1)'
Use of uninitialized value in substr at -e line 1.

None of the (uncommented) code above seems to be a pattern match, so I
think the line numbering must be off. Maybe you could post a
self-contained script (sans line numbers) that exhibits the problem?

Jon
 
J

John Bokma

Lukas said:
Sam Denton schrob:

That's weird because line 218 is `my $firstchar = substr($fsmount,0,1)'.
In fact, I don't see any m// in your code (except for the comment in
line 216).

If Sam is using an old version of Perl, *and* uses elsif, the line number
(s) reported can be wrong.
 
S

samwyse

Sam Denton schrob:



That's weird because line 218 is `my $firstchar = substr($fsmount,0,1)'.
In fact, I don't see any m// in your code (except for the comment in
line 216).

Your code and your error messages don't agree.

Yes, I noticed that as well. Originally, my code only had lines 208,
216-217, and 220; the other lines are debugging code that I've added
trying to track things down. The message has always been the same
except for the line number, which has always pointed to whichever came
first of the "if" statement or the call to "substr". The message has
always said "pattern match" and I think that its always said "(m/)",
regardless of the way I coded the regex.

I suspect that the (m//) is a generic message for any pattern match; I
further wonder if, internally, the substr is getting translated into a
pattern match. The Perl optimizer does some strange things sometimes.

I posted the original question about two minutes before leaving work
today (my wife had to get our daughter to girl scouts), but I can
double-check things tomorrow. I'll also try shrinking the code down to
the minimum that exhibits the problem.
 
T

Tad McClellan

Sam Denton said:
OK, my first post had a bug, but it's a real problem, honest.


Post a short and complete program *that we can run* that
makes those warnings, and we will help you make the warnings
go away.
 
P

Peter Hickman

Sam said:
OK, my first post had a bug, but it's a real problem, honest.

Here's my (fixed!) code:

+208 chomp ($fsmount);
+209 $fsmount .= ' ';
+210
+211 print "*** fsmount = \"$fsmount\"";
+212 print ", empty" if $fsmount eq "";
+213 print ", undef" unless defined($fsmount);
+214 print " ***\n";
+215
+216 # if ( $fsmount =~ m=^/= ) {
+217 # $fsmount =~ s/:.*$//;
+218 my $firstchar = substr($fsmount,0,1);
+219 if ( $firstchar eq '/' ) {
+220 $fsmount =~ s/:.*//;


Ok this is the problem. Line 212. Look at the following complete code.

# At this point $fsmount is undefined

print "*** fsmount = \"$fsmount\"";
print ", empty" if $fsmount eq "";
print ", undef" unless defined($fsmount);
print " ***\n";

# Now we switch the order of the tests

print "*** fsmount = \"$fsmount\"";
print ", undef" unless defined($fsmount);
print ", empty" if $fsmount eq "";
print " ***\n";

Now we run it.

*** fsmount = "", empty, undef ***
*** fsmount = "", undef, empty ***

So undef is the same as "". In effect the test coerced the undef into an empty
string.

Reorder your tests.
 
M

Michele Dondi

OK, my first post had a bug, but it's a real problem, honest. [snip]
string. Everything works just fine without the '-w' option. Any ideas?

Well, when I read your post yesterday I was too tired to read your
actual code, even if you had been sensible enough to quote only the
relevant lines. Taking this into account I answered the way I did, but
when I noticed the error you were doing, as pointed out by many people
here, I regretted having done so. However that *may* still apply,
though I *recommend* you do that only if you're sure you're not doing
another mistake like the previous one.

If the warning is really "spurious", i.e. you *do* know why you're
getting it, but do not want to hear it anyway, then as I already
suggested, just locally disable 'uninitialized' warnings.


HTH,
Michele
 
T

Tad McClellan

samwyse said:
As I previously posted, I will try to reduce the program to something
smaller that reproduces the error. This might take a while because the
program is parsing AIX-specific files and removing the system
dependencies could be, hmmm, fun.


There is a high probability that the problem will reveal itself
to you as you go through the exercise described above.

Which is why the Posting Guidelines suggest such an exercise. :)
 
M

Michele Dondi

to find one. That usually indicates a failure on my part, but in this
case I also am using 'use strict;' and it, too, fails to find anything
wrong when the '-w' option is removed. Either there's a very subtl

As a side note C<use strict;> and C<use warnings;> are to a large
extent orthogonal. Hence your claim doesn't make *much* sense...


Michele
 
B

Ben Morrow

Quoth Michele Dondi said:
As a side note C<use strict;> and C<use warnings;> are to a large
extent orthogonal. Hence your claim doesn't make *much* sense...

To be fair, a common source of 'use of uninit value' warnings is
misspelling variable names when not using strict, so the OP is simply
saying that he has eliminated that possible source of error.

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top