[comp.lang.perl] perl bugs in pl41

rep@genrad.com (Pete Peterson) (12/06/90)

 The following bugs all exist in perl 3.41 on all platforms unless otherwise
noted.

---------------------------------------------------------------------------
There is a bug which appears when grep is used with a filetest or
expression including a filetest as the condition and a wildcard expansion
as the list.  There may be other manifestations, but this was the simplest
one I could generate.

Trivial Example:

perl -we '$,="\n";print grep(-d,<*>),"\n";'

  This should print a list of the directories in the current directory.
  It actually prints error messages like the following and also produces
  incorrect output (the latter, even if -w be omitted):

  "Use of uninitialized variable at /tmp/perl-ea03382 line 1, <_GEN_0> line 5."

  You get one message for each file in the wildcard expansion.

Workaround:

perl -we '$,="\n";print grep(-d,@bug=<*>),"\n";'

  This works as expected, with -w giving only the warning about the
  variable which appears only once.

---------------------------------------------------------------------------

We have discovered a bug (on all platforms) wherein a postincremented
string variable used as a file handle works improperly; namely, it uses the
incremented value as the filehandle.  I reported this bug by mail last
August, but never got any feedback.

Simplified example:
    This script should open file "foo" with filehandle "OUT1" and should
    therefore print "OUT1".  It actually prints "OUT2".

#!/usr/local/perl
$FILE="OUT1";
open($FILE++, ">foo");
print "OUT1\n" if -e OUT1;
print "OUT2\n" if -e OUT2;

---------------------------------------------------------------------------

There is a bug on the pmax (decstation) which appears to relate to integers
with the MSB set.  The following works fine on suns and vaxes but fails in
different ways with perl 3/18 and perl 3/41 on the pmaxen:

printf (" %x, %x, %x, %x\n", 0xffffffff, 0xf0000000, 0x81234567, ~0xffff);
printf (" %x, %x, %x\n", 0xfffffff<<4, 15 << 28, ~1);
$a = 0xffff0000 & 7; $b = 15 << 28 & 7; print " a is $a; b is $b\n";

Should print (and does except on pmax):
 ffffffff, f0000000, 81234567, ffff0000
 fffffff0, f0000000, fffffffe
 a is 0; b is 0
--------------------
In perl41 on pmax, you get:
 7fffffff, 7fffffff, 7fffffff, 7fffffff
 fffffff0, f0000000, 7fffffff
 a is 7; b is 0
--------------------
In perl18 on pmax, you get:
 ffffffff, f0000000, 81234567, 7fffffff
 fffffff0, f0000000, 7fffffff
 a is 0; b is 0

This problem can be worked around by editing config.sh, at the end of
running Configure, to make "d_castneg='undef'".

---------------------------------------------------------------------------

There is an additional idiosyncrasy which relates to <globstring>
expansions in recursive subroutine calls.  I don't have a nice compact
example handy, but it appears in things like


sub recurse {
	local $foo;
	.
	.
	foreach $foo (<xxx.yy*>) {
		.
		.
		do recurse(aaa,bbb);
		.
		.
		}
	.
	.
	}

What appears to happen is that when the subroutine exits up to the previous
instance of itself, the $foo at that level doesn't get the next list
element of the glob operation.

Replacing "foreach $foo (<xxx.yy*>)" with @ary=<xxx.yy*>; foreach $foo (@ary)"
(with a "local @ary;" in the subroutine) appears to work as expected.

---------------------------------------------------------------------------
	pete peterson
	rep@genrad.com
	{decvax,linus,wjh12,mit-eddie,masscomp}!genrad!rep

fuchs@it.uka.de (Harald Fuchs) (12/06/90)

rep@genrad.com (Pete Peterson) writes:

> The following bugs all exist in perl 3.41 on all platforms unless otherwise
>noted.

>There is a bug on the pmax (decstation) which appears to relate to integers
>with the MSB set.  The following works fine on suns and vaxes but fails in
>different ways with perl 3/18 and perl 3/41 on the pmaxen:

>printf (" %x, %x, %x, %x\n", 0xffffffff, 0xf0000000, 0x81234567, ~0xffff);
>printf (" %x, %x, %x\n", 0xfffffff<<4, 15 << 28, ~1);
>$a = 0xffff0000 & 7; $b = 15 << 28 & 7; print " a is $a; b is $b\n";

>Should print (and does except on pmax):
> ffffffff, f0000000, 81234567, ffff0000
> fffffff0, f0000000, fffffffe
> a is 0; b is 0
>--------------------
>In perl41 on pmax, you get:
> 7fffffff, 7fffffff, 7fffffff, 7fffffff
> fffffff0, f0000000, 7fffffff
> a is 7; b is 0
>--------------------
>In perl18 on pmax, you get:
> ffffffff, f0000000, 81234567, 7fffffff
> fffffff0, f0000000, 7fffffff
> a is 0; b is 0

>This problem can be worked around by editing config.sh, at the end of
>running Configure, to make "d_castneg='undef'".

Alternatively, you could use a reasonable C compiler, e.g.
gcc-osf-1.9.2.13.tar.Z from foobar.colorado.edu.

I compiled perl with this gcc (even with -O!) and the script above
returned the correct results.
--

Harald Fuchs <fuchs@it.uka.de> <fuchs%it.uka.de@relay.cs.net> ...
<fuchs@telematik.informatik.uni-karlsruhe.dbp.de>   *gulp*

eichin@athena.mit.edu (Mark W. Eichin) (12/11/90)

Mr. Peterson (and other perl-users): 
 First, please pardon me if this seems to ramble, I've been adding
bits and pieces of further info on these compiler problems as I
acquire them. Summary: Configure's cast_neg test appears to be
incorrect, and the result of this behavior isn't caught by any of the
test scripts.

I tried your example
|>printf (" %x, %x, %x, %x\n", 0xffffffff, 0xf0000000, 0x81234567, ~0xffff);
|>printf (" %x, %x, %x\n", 0xfffffff<<4, 15 << 28, ~1);
|>$a = 0xffff0000 & 7; $b = 15 << 28 & 7; print " a is $a; b is $b\n";

under PL41 on all platforms I've built it on, and I've also seen
strange things. I originally noticed this class of bug (~ ^ and other
bitwise things) when porting Dennis Ferguson's DESTOO implementation
of DES to perl (it was easy... I might even be able to post a perl
script which performs the edits, so as not to violate (1) his
copyright (2) US State Department export regulations)...

os: IBM PC/RT AOS 4.3 (Athena 7.1)
cc: MetaWare hc2.1y -Hon=read_only_strings -Z -g -O
 ffffffff, f0000000, 81234567, 0
 fffffff0, f0000000, 0
 a is ; b is
(This version also fails any of the lib.big tests involving negative
numbers, which I've reduced to the example 
	./perl -e 'printf "%x\n",1^63;' --> 0
 which makes lib.big fail because it uses ^=ord('-')^ord('+') to
change sign in &bneg. I thought this was a grammar issue, except that
it doesn't fail on the Vax.) I'll try the cast_neg=undef workaround,
but if any of you have suggestions for what section of the code might
be failing here, I'd appreciate them. MetaWare "High C" is noted for
its "interesting" interpretations of the C language - it tends to do
things which are legal under the ANSI C spec, but are in an "unusual"
section of the undefined behavior. Though people have defended the
2.1y release, I'm prone to start with an assumption of a compiler bug
(or at least "dark alley").
	Further note: I took the try.c file for the cast_neg case,
added the line
	printf("%lx,%x,%x\n",along,aint,ashort);
and got
	7b,7b,ff85
from it (all of these were unsigned whatever cast from double f= -123)
The vax (gcc or pcc, below) gives 
	ffffff85,ffffff85,ff85
as does gcc 1.35.99 on the RT (which isn't really trusted.)  I
suspect Configure is mistaken in assuming that as long as none of them
are 0 it's "safe" to use this feature, but I'm not really sure how
perl is (mis?)using this language feature. From my reading of the
dpANS (yeah, I should get an update to the final spec):
	3.2.1.2 (particularly footnote 22) indicate that the vax
behavior is as specified for conversion of (for example) signed
integer -123 to unsigned integer (the gist is that the two's
complement representation remain the same.) However,
	3.2.1.3 indicates that if the value of the integral part of a
floating point value can not be represented by the integral type it is
being converted to, "the behavior is undefined". This is emphasised in
footnote 23, which indicates "Thus the range of portable values is
[0,UtypeMAX+1)." 
	In other words,	cast_neg should probably *always* be undef,
for portability, if it is truly based on the test given in Configure.

os: VAX BSD 4.3 (Athena 7.2)
cc: gcc -c -fpcc-struct-return -DDEBUGGING -g -O (1.37.92)
 ffffffff, f0000000, 81234567, ffff0000
 fffffff0, f0000000, fffffffe
 a is 0; b is 0

(which we all agree is correct. Good old Vaxen, they're slow but they
do what everyone expects...)

os: Ultrix Worksystem 2.1 (version 14) [ie. Ultrix 3.1] (Athena 7.2)
cc: cc2.1 -g but d_volatile='undef'
 7fffffff, 7fffffff, 7fffffff, 7fffffff
 fffffff0, f0000000, 7fffffff
 a is 7; b is 0
	So much for this compiler - test "cmd.for" runs forever.
However, the cast_neg test above gives the same numbers as the Vax for
both cc2.1 -g and gcc -g -O. (The latest gcc we have around here gets
a strange assembler error on consarg.c, I'm looking for a newer
version to see if that helps.)

				_Mark_ <eichin@athena.mit.edu>
-- "Perl is APL on LSD. -- Seth Finkelstein <sethf@athena.mit.edu>"