VSarkiss has asked for the wisdom of the Perl Monks concerning the following question:

I ran into this problem just this morning, and it's got me very curious.

The following short program, instead of triggering a syntax error, causes my perl (AS 5.8.4 on WinXP, details below) to hang up.

#!perl $rec = { avg_outst => pfo... # BAD pct_pfo => ' ', };
By "hang up" I mean it never returns: task manager reports perl.exe using 99% of the cpu, and eating up more and more memory.

By way of explanation, this is part of a larger program I was writing, with several other fields in the hash, way down in a sub. I'd left the "pfo..." bit as a reminder to myself to come back and pull out what I wanted from the $pfo structure. Imagine my surprise when my program wouldn't even compile: not even perl -c would work.

I found the errant code by commenting out parts until I found the error, and then the fix was easy. But I'm still very curious why it happened. I went back and ripped out everything else to make the smallest test case I could, and I'm pretty sure this is it. If I remove the next line (the one starting pct_pfo =>), perl reports the syntax error and stops, as you might expect. BTW, the original was using strict and warnings.

Am I missing something obvious? This is just a plain syntax error, not some obscure abbreviation for while (1), correct? :-) Why does it completely tie up perl?

Installation details follow. I'd be curious if it happens on other platforms.

Summary of my perl5 (revision 5 version 8 subversion 4) configuration: Platform: osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread uname='' config_args='undef' hint=recommended, useposix=true, d_sigaction=undef usethreads=undef use5005threads=undef useithreads=define usemultip +licity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cl', ccflags ='-nologo -Gf -W3 -MD -Zi -DNDEBUG -O1 -DWIN32 -D +_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DNO_HASH_SEED -DPERL_IMPLICI +T_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -DPERL_MSVCRT_READFIX', optimize='-MD -Zi -DNDEBUG -O1', cppflags='-DWIN32' ccversion='', gccversion='', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='__int64 +', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf -l +ibpath:"D:\Perl\lib\CORE" -machine:x86' libpth=C:\PROGRA~1\MICROS~3\VC98\lib libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netap +i32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.li +b odbccp32.lib msvcrt.lib perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool +.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib n +etapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msv +crt.lib libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl58.lib gnulibc_version='undef' Dynamic Linking: dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' ' cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug -opt: +ref,icf -libpath:"D:\Perl\lib\CORE" -machine:x86' Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY USE_ITHREADS USE_LARGE_FILES PERL +_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS Locally applied patches: ActivePerl Build 810 22751 Update to Test.pm 1.25 21540 Fix backward-compatibility issues in if.pm Built under MSWin32 Compiled at Jun 1 2004 11:52:21 %ENV: PERL5LIB="F:\oracle\product\10.1.0\Db_1\sysman\admin\scripts" @INC: F:\oracle\product\10.1.0\Db_1\sysman\admin\scripts D:/Perl/lib D:/Perl/site/lib .

Update:
It's not a syntax error. The ... is a range operator, which perl tries to process at compile time when (both?) ends of the list are constants. That's probably good when the list is small, but is potentially disastrous when the list ends are very far from each other. Even warnings can't get a hold of it in time to say, "Possibly enormous list at line 3" or some such. So it looks like it hung up.

Replies are listed 'Best First'.
Re: Syntax error makes perl hang
by eric256 (Parson) on Aug 15, 2005 at 20:11 UTC

    Actualy you don't have a syntax error. Just a bit of unintended code. ;) I beleive perl is reading it like below..... It isn't hung, just taking a long time to compute all the combinations between pfo and pct_pfo which is a rather large number i'm guessing.

    #!perl $rec = { avg_outst => pfo...pct_pfo, ' ', };

    ___________
    Eric Hodges

        Here is an odd piece in deed. Apparently it is dependent on the actual names you are using in that they contain a _. I have no idea why but check this out.

        C:\Perl\Tests>perl -c -e"$var = { aa...aaaa}" -e syntax OK C:\Perl\Tests>perl -c -e"$var = { aa...aaaa_}" C:\Perl\Tests>perl -c -e"$var = { 'aa'...'aaaa_'}" C:\Perl\Tests>

        The last two had to be killed as they consumed all the processors power. The first flew through in no time, obviously not computing. So some little thing is causeing the _ to make it actualy execute that code.

        BTW C:\Perl\Tests>perl -c -e"'aa'...'aaaa_'" without the hash ref doesn't cause any delay, and checks out perfectly.


        ___________
        Eric Hodges
        To add to the detective work, changing to
        #!/usr/bin/perl $rec = { avg_outst => pct_pf... # BAD pct_pfo => ' ', };
        gives me
        C:\Perl>perl -MO=Deparse testhang.pl $rec = {'avg_outst', 'pct_pf', ' '}; testhang.pl syntax OK

        At a guess it is trying to create the result list at compile time.

        /J\

Re: Syntax error makes perl hang
by ikegami (Patriarch) on Aug 15, 2005 at 20:14 UTC

    This also causes my perl (ActivePerl v5.6.1) to hang in the compile phase.

    By the way, ... is a Perl operator. Since it can be found in code, and since it's often found in messages and comments, I usually avoid using ... to note places which need editing. (I use ~~~, but that has a chance of producing valid Perl code.)

Re: Syntax error makes perl hang
by cfreak (Chaplain) on Aug 15, 2005 at 20:21 UTC
Re: Syntax error makes perl hang
by Transient (Hermit) on Aug 15, 2005 at 20:13 UTC
    Since I couldn't get B::Deparse to work with this, I can't say for certain, but I think it's interpreting the ... as a range operator.

    If you make it a .. it does the same thing.

    Changing it to a . runs successfully with no output.
Re: Syntax error makes perl hang (hint)
by tye (Sage) on Aug 16, 2005 at 00:26 UTC
    $ perl -MO=Deparse -e '@x=(0...9)' @x = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9); -e syntax OK $

    - tye        

        No, it's an even better idea to do it at compile time if the list is large. The larger the list, the larger the potential savings by precomputing it once at compile time.
Re: Syntax error makes perl hang
by anonymized user 468275 (Curate) on Aug 16, 2005 at 08:29 UTC
    To be precise, a downward range is empty. For example,
    print 0...1; print "\n";
    produces the result
    01
    but inverting the 0 and 1 produces an empty line. z...a had no noticable effect -- still an empty line, but zzzzzzz...aaaaaaa did indeed cause perl to go into huddle while it was presumably calculating the combinations even though it should arguably know that it should promptly exit the range with an empty result when the second argument is lower than the first.

    I consider this a missed optimisation opportunity in perl.

    One world, one people

Re: Syntax error makes perl hang
by NiJo (Friar) on Aug 16, 2005 at 17:47 UTC
    Workaround: use warnings;