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

Hi,

I'm pretty new to perl and got a question regarding the pack/unpack function. I use perl under win32 (ActivePerl).
print unpack('N1', '(òÿÿ')."\n"; # gives '687013887' print unpack('l1', '(òÿÿ')."\n"; # gives '-3544'

Is this a normal behaviour? The first line of code is used in a unix based perl script (SpamAssassin) to fork. If I try this under windows it leads to some issues. If I change it from 'l1' to 'N1' it's working fine.

Have a look here or tell me, if you need additional information.

Thanks in advance!

Replies are listed 'Best First'.
Re: signed and unsigned templates in pack/unpack
by jmcnamara (Monsignor) on Mar 02, 2010 at 09:37 UTC

    The 'N' template will always give an unsigned 32-bit value which will be the same on big or little endian hardware.

    The 'l' template gives a signed 32-bit value which will be different on big or little endian hardware. See the pack() perldoc.

    So in answer to your question, this is normal behaviour. If you are getting different behaviour on Windows it shouldn't be due to this line of code, per se, but rather to how the return value is used. *

    In this particular case I'd guess that the issue isn't that the pid is being unpacked as 'N' or 'l' but rather that it is being repacked as 'I' rather than 'N'. That is just a guess though, without digging further into the code.

    * What seems strange about using 'l' in this case is that it could give a negative pid on Windows. Is that valid? If not then it is an indication that the problem lies elsewhere.

    P.S. The '1' in the unpack templates is superfluous and in the case of 'l1' a little confusing.

    --
    John.

      The returned pid is used in a sub which checks if the pid already exists. Due the fact, pack and unpack using the same template but returning different values this is a big problem.

      print pack ('N', -3544)."\n"; # gives 'ÿÿò(' print unpack ('N', 'ÿÿò(')."\n"; # gives '4294963752'

      Shouldn't unpack return -3544 again?

        You're packing a negative number with an unsigned template 'N', which means it will be treated as a large positive value. And when you unpack it, it will return that large positive value.

        The solution is don't use an unsigned template for packing numbers than can be negative. Use a signed template:

        $p = pack 'j', -3544;; print unpack 'j', $p;; -3544

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.