Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

warnings pragma anomaly

by Athanasius (Archbishop)
on Oct 17, 2015 at 04:17 UTC ( [id://1145179]=perlquestion: print w/replies, xml ) Need Help??

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

It is completely unimportant. That is why it is so interesting.
— Hercule Poirot in The Murder of Roger Ackroyd by Agatha Christie

While researching Re^3: Perl assign scalar to array I noticed something strange. In this one-liner:

13:54 >perl -we "my $scalar = (2, 3, 4); print $scalar;" Useless use of a constant (2) in void context at -e line 1. Useless use of a constant (3) in void context at -e line 1. 4 13:54 >

the term (2, 3, 4) is evaluated in scalar context, so the comma operator (which is left-associative) twice “evaluates its left argument, throws that value away, then evaluates its right argument and returns that value.” The first two constants are thrown away, so the warning messages are exactly as expected.

But when certain constants are used, the warning messages for those constants disappear. I have found three such constants: 0, 1, and undef. For example:

14:00 >perl -we "my $scalar = (2, 1, 4); print $scalar;" Useless use of a constant (2) in void context at -e line 1. 4 14:00 >

Deparsing sheds no light, since the result is the same in all cases:

14:00 >perl -MO=Deparse -we "my $scalar = (2, 1, 4); print $scalar;" Useless use of a constant (2) in void context at -e line 1. BEGIN { $^W = 1; } my $scalar = ('???', '???', 4); print $scalar; -e syntax OK 14:01 >perl -MO=Deparse -we "my $scalar = (2, 3, 4); print $scalar;" Useless use of a constant (2) in void context at -e line 1. Useless use of a constant (3) in void context at -e line 1. BEGIN { $^W = 1; } my $scalar = ('???', '???', 4); print $scalar; -e syntax OK 14:01 >

I tested this on the earliest and latest Perls currently installed on my system: v5.14.4 and v5.22.0 (both Strawberry Perl running under Windows 8.1, 64-bit).

Any ideas as to why these three particular constants should be treated differently by the warnings pragma?


I tried looking at the code in warnings.pm, but, as far as I can see, the only effect of use warnings is to call warnings::import, which in turn sets ${^WARNING_BITS}. Presumably, this variable affects the behaviour of the perl executable? Does anyone know where in the source code the real functionality behind use warnings resides?

Cheers,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re: warnings pragma anomaly
by BrowserUk (Patriarch) on Oct 17, 2015 at 04:32 UTC

    Constants 0 & 1 are special cased exclusions from the "void context" warning because they are so useful.

    Eg. 1 while s[...][...]g;; does search and replace until no more matches are found.

    There are many other examples of the utility of having 0, 1 & undef in a void context fail to warn. I seem to recall a thread that listed them; though a cursory search failed to locate same.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    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". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: warnings pragma anomaly
by LanX (Saint) on Oct 17, 2015 at 08:48 UTC
    I seem to remember that 0 and 1 in void context are documented as a form of NOP (no operation) in Perl, but I'm failing to find the corresponding perldoc.

    edit

    ahh, it's in perlop

    No-ops Perl doesn't officially have a no-op operator, but the bare con +stants 0 and 1 are special-cased to not produce a warning in a void cont +ext, so you can for example safely do 1 while foo();

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

Re: warnings pragma anomaly
by AppleFritter (Vicar) on Oct 17, 2015 at 09:37 UTC

    Does anyone know where in the source code the real functionality behind use warnings resides?

    That's in op.c for this particular warning; the relevant code (currently) starts at line 1948, with the check itself starting at line 1954:

    1948                 if (ckWARN(WARN_VOID)) {
    1949                     NV nv;
    1950                     /* don't warn on optimised away booleans, eg
    1951                      * use constant Foo, 5; Foo || print; */
    1952                     if (cSVOPo->op_private & OPpCONST_SHORTCIRCUIT)
    1953                         useless = NULL;
    1954                     /* the constants 0 and 1 are permitted as they are
    1955                        conventionally used as dummies in constructs like
    1956                        1 while some_condition_with_side_effects;  */
    1957                     else if (SvNIOK(sv) && ((nv = SvNV(sv)) == 0.0 || nv == 1.0))
    1958                         useless = NULL;
    1959                     else if (SvPOK(sv)) {
    1960                         SV * const dsv = newSVpvs("");
    1961                         useless_sv
    1962                             = Perl_newSVpvf(aTHX_
    1963                                             "a constant (%s)",
    1964                                             pv_pretty(dsv, SvPVX_const(sv),
    1965                                                       SvCUR(sv), 32, NULL, NULL,
    1966                                                       PERL_PV_PRETTY_DUMP
    1967                                                       | PERL_PV_ESCAPE_NOCLEAR
    1968                                                       | PERL_PV_ESCAPE_UNI_DETECT));
    1969                         SvREFCNT_dec_NN(dsv);
    1970                     }
    1971                     else if (SvOK(sv)) {
    1972                         useless_sv = Perl_newSVpvf(aTHX_ "a constant (%"SVf")", SVfARG(sv));
    1973                     }
    1974                     else
    1975                         useless = "a constant (undef)";
    1976                 }
    

    The special case for 0 and 1 was introduced in April 2001 in this commit (in Perforce rather than git back in those days, of course).

Re: warnings pragma anomaly ( missing Useless use of %s in void context not issued)
by Anonymous Monk on Oct 17, 2015 at 09:18 UTC
Re: warnings pragma anomaly
by ikegami (Patriarch) on Oct 19, 2015 at 16:21 UTC
    As for undef, it's not just a function that returns an undefined value; it's a function that undefines its arguments.
    undef $foo; # Similar to $foo = undef; but also frees memory.

    As such, it's perfectly fine to call undef in void context.

Re: warnings pragma anomaly
by muba (Priest) on Oct 19, 2015 at 17:23 UTC

    Another place where using 1 in void context is commonplace is near/at the end of modules. When use Foo loads Foo.pm, then the last expression evaluated inside Foo.pm better be a true value, to signal that the module loaded succesfully. That's why you usually see the line

    1;
    near or at the end of a .pm file. Because 1 evaluates to a true value, but is special-cased not to raise a warning.

      As the return value of this expression is returned and checked for truthness, it's not used in a void context. Moreover, you can use any true value at the end of a module, and you won't get any warnings. See also Acme::ReturnValue.

      Update: You can check the generated lists here.

      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
        As the return value of this expression is returned and checked for truthness, it's not used in a void context.

        Are you sure about that? If you end a package with just: 1; no warning is produced; but if you end it with just: 42;:

        C:\test>perl -Mstrict -w package x; sub f{ 1 } 42; ^Z Useless use of a constant in void context at - line 5.

        Although it is returned and checked at runtime; at the point of parsing it is in a void context.

        And you can't avoid that by prefixing a return statement either:

        C:\test>perl -Mstrict -w package x; sub f{ 1 } return 42; ^Z Can't return outside a subroutine at - line 3.

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        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". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1145179]
Front-paged by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2024-04-19 09:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found