http://www.perlmonks.org?node_id=330691

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

I fount that the statement $#="%c"; has strange side effects on operations other than stringifying floating-points. For example

perl -we '$#="%c"; print ord ("k"), $/;'
Prints only a \0\n, while it should print 107\n.
perl -we 'print ord ("k"), $/;'
works correctly. Could someone tell me why is this, is this really a bug?

This affects all versions of perl on my i686-linux system, that is 5.8.1, 5.8.0, 5.6.1, 5.00503.

Replies are listed 'Best First'.
Re: $#="%c"; possible bug
by Abigail-II (Bishop) on Feb 20, 2004 at 23:31 UTC
    Setting $# sets the output format for printed numbers. I don't see why you expect '107' to be printed, I would expect 'k' to be printed.

    But $# has been broken for eons, and it has been deprecated for even longer. I've never seen it used in code that wasn't intentionally obfuscated.

    Abigail

      ord('k') is 107 so it should print 107, and the first statement should not affect it.

      Is $# really broken for eons? Where's that from? See my reply for the other post Re: Re: $#="%c"; possible bug.

      Update: effect->affect

        ord('k') is 107 so it should print 107
        Uhm, no.
        the first statement should not effect it.
        Yes, it should. To quote myself: Setting $# sets the output format for printed numbers. 107 is still a number in my book.

        From man perlvar:

        $# The output format for printed numbers. This vari­ able is a half-hearted attempt to emulate awk's OFMT variable. There are times, however, when awk and Perl have differing notions of what counts as numeric. The initial value is "%.ng", where n is the value of the macro DBL_DIG from your system's float.h. This is different from awk's default OFMT setting of "%.6g", so you need to set $# explicitly to get awk's value. (Mnemonic: # is the number sign.) Use of $# is deprecated.

        Is $# really broken for eons? Where's that from?
        Yes it is. Your code is proof.

        Abigail

Re: $#="%c"; possible bug
by BrowserUk (Patriarch) on Feb 20, 2004 at 23:27 UTC

    That could be why I get

    [23:26:02.98] P:\test> perl -we "$#='%c'; print ord ('k'), $/;" Use of $# is deprecated at -e line 1.

    from 5.8.3?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Timing (and a little luck) are everything!

      Perl 5.00503 and all others print that message too. But I don't see a note in perldoc anywhere that it would cause such disasters. It's simply depr.

Re: $#="%c"; possible bug
by ambrus (Abbot) on Feb 21, 2004 at 18:20 UTC

    After abigail's post, it's clear how $# works. Perl calls the builtin sprintf with a single floating point argument, and the resulting text is the string representation of the number (if $# is set). You can even decompose a double to two ints by setting $# to "%x/%x". This explains the strange strange phenomena that setting $# to a stupid value causes.

    However, as an interesting consequence you can still segfault perl with some code like perl -we '$#="%s\n"; print exp 1;' or perl -we '$#="%n\n"; print exp 1;'

Re: $#="%c"; possible bug
by ambrus (Abbot) on Feb 25, 2004 at 16:52 UTC