A Spurious Warning

R

Rainer Weikusat

Below is a Perl subroutine supposed to parse a CIDR IPv4 network
specification and return the numerical values of the first and last
addresses in this range (this code is (c) my employer and quoted here
for educational purposes):

sub parse_net_spec($)
{
my ($first, $mask, @octets, $prefix);

$_[0] =~ /^((?:\d{1,3}\.){0,3}\d{1,3})\/(\d\d?)$/ && do {
$prefix = $2;
die('prefix too large') unless $prefix < 33;

@octets = split(/\./, $1);
for (@octets) {
die('octet too large') unless $_ < 256;
$first = $first << 8 | $_;
}
$first <<= 8 * (4 - @octets);

$mask = (1 << (32 - $prefix)) - 1;
return ($first & ~$mask, $first | $mask);
};

die("'$_[0]' does not look like a CIDR network specification");
}

As far as I know, this function is correct in the sense that it should
reject any invalid input and produce the intended result for each
valid one (information to the contrary very much welcome). This will,
of course, given a suitably adjusted perl invocation, result in a

Use of uninitialized value $first in left bitshift (<<)

warning, despite the automatic conversion which is going to take place
here will result in the correct value (0).

What was the precise reason why this is supposed to be 'something that
should not be'?
 
R

Randal L. Schwartz

Rainer> my ($first, $mask, @octets, $prefix);

....

Rainer> $first = $first << 8 | $_;

....

Rainer> As far as I know, this function is correct in the sense that it should
Rainer> reject any invalid input and produce the intended result for each
Rainer> valid one (information to the contrary very much welcome). This will,
Rainer> of course, given a suitably adjusted perl invocation, result in a

Rainer> Use of uninitialized value $first in left bitshift (<<)

You never initialize $first.

Just like it says. :)

This is why I really discourage:

my ($list, $of, $variables);

You should introduce each variable at a time when you have a meaningful
initial value:

my $first = 0;

and so on.

print "Just another Perl hacker,"; # the original
 
C

Charlton Wilbur

RW> This will, of course, given a suitably adjusted perl invocation,
RW> result in a

RW> Use of uninitialized value $first in left bitshift (<<)

RW> warning, despite the automatic conversion which is going to take
RW> place here will result in the correct value (0).

RW> What was the precise reason why this is supposed to be
RW> 'something that should not be'?

Generally, performing arithmetic on undefined values is a sign of an
error or an omission. The Perl compiler cannot infer your intent from
the code, and so errs on the side of caution by issuing a warning.

In this case, the automatic conversion is what you intend and what you
expect. If the warning bothers you, silence it with "no warnings
'uninitialized';" or don't "use warnings;" in the first place.

Charlton
 
R

Rainer Weikusat

Rainer> my ($first, $mask, @octets, $prefix);

...

Rainer> $first = $first << 8 | $_;

...

Rainer> As far as I know, this function is correct in the sense that it should
Rainer> reject any invalid input and produce the intended result for each
Rainer> valid one (information to the contrary very much welcome). This will,
Rainer> of course, given a suitably adjusted perl invocation, result in a

Rainer> Use of uninitialized value $first in left bitshift (<<)

You never initialize $first.

Just like it says. :)

Well, yes. perl initializes $first to 'an undefined value' (which is
actually a well-defined value with a specific property) and the result
of converting this 'undefined null string', as the perldata(1) manpage
calls it, to a number is the number zero. Which happens to be the
numerical value needed at the 'place' of the calculation where it is
being used.
 
R

Rainer Weikusat

Charlton Wilbur said:
RW> This will, of course, given a suitably adjusted perl invocation,
RW> result in a

RW> Use of uninitialized value $first in left bitshift (<<)

RW> warning, despite the automatic conversion which is going to take
RW> place here will result in the correct value (0).

RW> What was the precise reason why this is supposed to be
RW> 'something that should not be'?

Generally, performing arithmetic on undefined values is a sign of an
error or an omission.

Given that this is a well-defined operation and has always been one,
this statement seems unjustifiable to me. Especially since a newly
created variable with no explicitly assigned other value will start
its 'arithmetic life' as zero and this is obviously useful whenever
some series of arithmetic operations involving said variable is
supposed to start with a value of zero.

As I wrote in a past posting: This is a feature I have always liked in
Perl because it means explicit initialization is not necessary when 'a
null value' of some suitable type is all that is needed (meaning,
something which is ether undefined, false, 0 or '', depending on what
use it is supposed to be put to).
 
C

Charlton Wilbur

RW> Given that this is a well-defined operation and has always been
RW> one, this statement seems unjustifiable to me.

The compiler cannot infer your intent. The compiler cannot distinguish
between a variable that you have left undefined because you are a
brilliant programmer who expects the undefined value to be converted to
0 in an arithmetic context, and a variable that you have left undefined
because you are a novice programmer who doesn't know any better.

Not making your intent clear to the compiler -- and to maintenance
programmers -- by explicitly initializing the variable to 0 or turning
off uninitialized value warnings *is* an error or an omission.

Charlton
 
M

Mart van de Wege

Charlton Wilbur said:
RW> This will, of course, given a suitably adjusted perl invocation,
RW> result in a

RW> Use of uninitialized value $first in left bitshift (<<)

RW> warning, despite the automatic conversion which is going to take
RW> place here will result in the correct value (0).

RW> What was the precise reason why this is supposed to be
RW> 'something that should not be'?

Generally, performing arithmetic on undefined values is a sign of an
error or an omission. The Perl compiler cannot infer your intent from
the code, and so errs on the side of caution by issuing a warning.
I applaud your patience, but let's be fair: Rainer has been riding his
hobby horse against 'uninitialized' warnings for months now.

By this time he is just trolling. Just killfile him.

Mart
 
R

Randal L. Schwartz

Rainer> Given that this is a well-defined operation and has always been one,
Rainer> this statement seems unjustifiable to me.

You lost me there. define "well-defined" and "always has", and we might
have room for a conversation.
 
C

Charlton Wilbur

MvdW> I applaud your patience, but let's be fair: Rainer has been
MvdW> riding his hobby horse against 'uninitialized' warnings for
MvdW> months now.

MvdW> By this time he is just trolling. Just killfile him.

I don't killfile - I use Gnus, which does an admirable job of noticing
what I care to read and skipping over posts I do not care to read. When
Gnus shows me a post by Rainer where he's engaged in his wingnuttery, I
respond with sanity. I figure if it helps at least one lurker to
understand that Rainer is a wingnut, it's worth the five minutes, and
it's a welcome brief distraction from what I'm actually supposed to be
working on.

Charlton
 
R

Rainer Weikusat

Rainer> Given that this is a well-defined operation and has always been one,
Rainer> this statement seems unjustifiable to me.

You lost me there. define "well-defined" and "always has", and we might
have room for a conversation.

There are actually two varieties of null strings (sometimes referred
to as "empty" strings), a defined one and an undefined one.

[...]

strings that aren't numbers count as 0, just as they do in awk

A null string (no matter if defined or undefined) "isn't a number",
hence, its numerical value is 0. This implies that the value of each
arithmetic operation involving (defined or undefined) 'null strings'
is predictable based on the defined semantics of the operater being
used and possibly, the numerical value of the other operand. Using a
free translation from a German Wikipedia page on 'Wohldefiniertheit':

In einem weiteren Sinn wird Wohldefiniertheit auch auf andere Bereiche
ausgedehnt. Sie bezeichnet dann eine sinnvolle und widerspruchsfreie
Definition.

In English, this should roughly be: [The term] well-definedness is
also used in a more general sense to mean sensible, non-contradictory
definition.

This interpretation of non-numerical strings as 0 is sensible in the
sense that it is consistent with a preexisting convention and
doesn't contradict itself.

As for the 'always has': Please provide quote which show that the
documented behaviour of Perl was different from the behaviour
documented in the quote above. This would demonstrate that 'it has
always been this way' [for Perl5] isn't true.
 
R

Rainer Weikusat

Mart van de Wege said:
I applaud your patience, but let's be fair: Rainer has been riding his
hobby horse against 'uninitialized' warnings for months now.

By this time he is just trolling. Just killfile him.

I've been arguing that well-defined default values for not otherwise
initialized variables are a good thing because this is a useful
feature and one which is 'logically sensible' (that was the statement
about 'null values' getting interpreted as 'something sensible'
depending on the use they are going to be put to: Asking wheter a null
value is defined should yield the answer 'no'. It should count as
'false'. Interpreted as a string, it should be regarded as an empty
string. Used as a number, the value should be 0). And I haven't
invented this: The same behaviour was obviously also considered
sensible by the people who wrote the corresponding compiler/
interpreter code because this is how 'undefined values' will be
interpreted, depending on the uses they are being put to.

In short: Perl has some features you HATE !!!!. You try to overcome
that by attacking people who claim they are useful => you are a troll.
 
A

Alan Curry

I've been arguing that well-defined default values for not otherwise
initialized variables are a good thing because this is a useful
feature and one which is 'logically sensible' (that was the statement
about 'null values' getting interpreted as 'something sensible'
depending on the use they are going to be put to: Asking wheter a null
value is defined should yield the answer 'no'. It should count as
'false'. Interpreted as a string, it should be regarded as an empty
string. Used as a number, the value should be 0). And I haven't
invented this: The same behaviour was obviously also considered
sensible by the people who wrote the corresponding compiler/
interpreter code because this is how 'undefined values' will be
interpreted, depending on the uses they are being put to.

In short: Perl has some features you HATE !!!!. You try to overcome
that by attacking people who claim they are useful => you are a troll.

From the amount of energy involved in your persistent posts, it sure looks
like you're the one who HATE!!!!s the fact that perl warns about certain uses
of undef, more than anyone else HATE!!!!s the fact that those uses of undef
have a documented outcome.

Think about this from another angle: is it a useful feature, in programming
lanugages generally, to have a value which causes an exceptional runtime
event (warning/death/coredump/takeyourpick) when it is used? I think so. You
can use that special value to mark variables that don't currently hold a
usable value. Then the warning (or whatever) becomes a debugging aid.

That's how most of us use undef. Your way is more like the original intent of
undef, as proven by the ancient documentation you keep quoting, but times
change and documentation doesn't always get updated, especially when what's
changed is not actual interpreter behavior but programmer attitudes.
 
R

Rainer Weikusat

From the amount of energy involved in your persistent posts, it sure looks
like you're the one who HATE!!!!s the fact that perl warns about certain uses
of undef,

But perl doesn't warn about 'certain uses of undef': Provided someone
goes to the length of unconditionally enabling all run-time warnings
perl is capable of generating, this particular warning will also be
enabled.

[...]
Think about this from another angle: is it a useful feature, in programming
lanugages generally, to have a value which causes an exceptional runtime
event (warning/death/coredump/takeyourpick) when it is used? I think
so. That's how most of us use undef.

But - your argument-unsupported opinion on that notwithstanding
- Perl doesn't have such a value. Instead, it has another kind of
'null value' with a different set features which are useful for
other situations. But if the language doesn't support some feature you
consider essential, and if you're into this type of 'theoretical
arguments about how things should really be instead of how they are',
why don't you just add your feature to the language and leave features
other people have found to be useful for them alone?

And if this can't be done (which is the case here), why don't you
simply use a language providing what you would like to have instead?
It's not that there would be a shortage of 'maximally
anally-retentative runtime environmens' ever since the misconception
that these would be essential came up 40 years ago
Your way is more like the original intent of That's how most of us
use undef. Your way is more like the original intent of undef, as
proven by the ancient documentation you keep quoting,

The presently most current perl version is 5.14.2. The most current
online version of the documentation (I was able to find without
spending much time on searching for it) is for 5.14.1. The manpage I
have been quoting in this thread is available here:

http://perldoc.perl.org/perldata.html

And it contains the exact text I quoted. Consequently, you statement
about 'ancient documentation' is factually incorrect, at least in this
context.
 
J

John W. Krahn

Rainer said:
Below is a Perl subroutine supposed to parse a CIDR IPv4 network
specification and return the numerical values of the first and last
addresses in this range (this code is (c) my employer and quoted here
for educational purposes):

sub parse_net_spec($)
{
my ($first, $mask, @octets, $prefix);

$_[0] =~ /^((?:\d{1,3}\.){0,3}\d{1,3})\/(\d\d?)$/&& do {
$prefix = $2;
die('prefix too large') unless $prefix< 33;

@octets = split(/\./, $1);
for (@octets) {
die('octet too large') unless $_< 256;
$first = $first<< 8 | $_;
}
$first<<= 8 * (4 - @octets);

You are missing a semi-colon (;) between the end of the do{} block and
the next statement.

$mask = (1<< (32 - $prefix)) - 1;
return ($first& ~$mask, $first | $mask);
};

die("'$_[0]' does not look like a CIDR network specification");
}


John
 
A

Alan Curry

The presently most current perl version is 5.14.2. The most current

This specific sentence of documentation:

There are actually two varieties of null string: defined and undefined.

was present in the man page for perl 3.0. Despite its survival in the current
version of perldata(1), it *is* ancient. Nobody would call the undefined
value a "variety" of a "null string" if they were writing the documentation
today.
 
T

Ted Zlatanov

RW> A null string (no matter if defined or undefined) "isn't a number",
RW> hence, its numerical value is 0.

I don't know how you arrived at that conclusion. Are you aware "infinity"
is not a number either? How about "minus infinity"?

Ted
 
T

Ted Zlatanov

RW> In short: Perl has some features you HATE !!!!. You try to overcome
RW> that by attacking people who claim they are useful => you are a troll.

Yup, that about sums it up. Nice job, Rainer.

Ted
 
M

Mart van de Wege

Rainer Weikusat said:
In short: Perl has some features you HATE !!!!. You try to overcome
that by attacking people who claim they are useful => you are a troll.

Well, if you attack people instead of arguments, then yes, you are a
troll.

Mart
 
R

Rainer Weikusat

This specific sentence of documentation:

There are actually two varieties of null string: defined and undefined.

was present in the man page for perl 3.0. Despite its survival in the current
version of perldata(1), it *is* ancient. Nobody would call the undefined
value a "variety" of a "null string" if they were writing the documentation
today.

Despite your attempts to weasel-word around this based on assumptions
about what hypothetical people would have done had they done something
(which I take as 'I [meaning, you] had never written that' [because I
want to bury this feature of Perl so that people obey to the arbitrary
other usage policy I'd like to force onto them'), whatever is
currently contained in the documentation is not 'ancient' but
'current' even although it may have been there 'since ancient times',
IOW, as I wrote in another posting, 'it has always been in this way'.

Something I really don't understand here is how the fact that some
people know the (technical) truth that perl assigns a sensible, useful
default value to newly created variables and consequently, write code
exploiting this feature, affects your ability to pretend that it
wasn't so (for a reason you didn't care to name). Why do you think
other people have to be conned into assuming that things are how you
would have liked them to be? And why does this difference in opinion
warrant attacking people with as much vitriol and 'threats of serious
real-life consequences' a la Mr Guttman as possible just for telling
the truth?
 
J

Jürgen Exner

Rainer Weikusat said:
Given that this is a well-defined operation and has always been one,
this statement seems unjustifiable to me. Especially since a newly
created variable with no explicitly assigned other value will start
its 'arithmetic life' as zero and this is obviously useful whenever
some series of arithmetic operations involving said variable is
supposed to start with a value of zero.

Just because Perl garantees a well-defined semantic to a specific
construct doesn't imply that it is a good idea to use it.

With the same argument you could refuse to use declarations because Perl
will automatically create a variable with first use. Nevertheless
hopefully there aren't many people who deny the usefulness of "my".

Or modules or indentations in Perl code. You can write any program
happily without them but luckily only very few people do.
As I wrote in a past posting: This is a feature I have always liked in
Perl because it means explicit initialization is not necessary when 'a
null value' of some suitable type is all that is needed (meaning,
something which is ether undefined, false, 0 or '', depending on what
use it is supposed to be put to).

If people never make mistakes then you wouldn't need variable
declarations, either.
But people do make mistakes and the additional cost of writing
my $var = 0
instead of
my $var
is so tiny that there is really no reason to ever risk wondering 5
months later if you did mean to use 0 or if you forgot to initialize it
to the correct value and 0 only happens to work in most cases.
Or worse: having someone else wondering and spending hours to
investigate.

jue
 

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,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top