develooper Front page | perl.perl5.porters | Postings from July 2013

[perl #118753] String constant used in elsif causes bogus warning

Thread Next
From:
yves orton
Date:
July 4, 2013 15:00
Subject:
[perl #118753] String constant used in elsif causes bogus warning
Message ID:
rt-3.6.HEAD-2552-1372949968-580.118753-75-0@perl.org
# New Ticket Created by  yves orton 
# Please include the string:  [perl #118753]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=118753 >


Found in perl 5.14.2 and in bleadperl, note the warning about constant
in void context:

$ ./perl -Ilib -lwe'BEGIN{eval "sub C() { q() }";} if ($x) { print 1 }
elsif (C) { print 2 }'
Useless use of a constant ("") in void context at -e line 1.
Name "main::x" used only once: possible typo at -e line 1.

Changing the constant to a 0 avoids the warning:

$ ./perl -Ilib -lwe'BEGIN{eval "sub C() { 0 }";} if ($x) { print 1 }
elsif (C) { print 2 }'
Name "main::x" used only once: possible typo at -e line 1.

Rafael points out that you dont need the constant for it:

$ ./perl -Ilib -lwe'if ($x) { print 1 } elsif ("") { print 2 }'
Useless use of a constant ("") in void context at -e line 1.
Name "main::x" used only once: possible typo at -e line 1.

And he explains that this is due to an optimization. Apparently we
should special case *any* false constant, not just 1 and 0.

The code involved is:

if (ckWARN(WARN_VOID)) {
                /* don't warn on optimised away booleans, eg
                 * use constant Foo, 5; Foo || print; */
                if (cSVOPo->op_private & OPpCONST_SHORTCIRCUIT)
                    useless = NULL;
                /* the constants 0 and 1 are permitted as they are
                   conventionally used as dummies in constructs like
                        1 while some_condition_with_side_effects;  */
                else if (SvNIOK(sv) && (SvNV(sv) == 0.0 || SvNV(sv) == 1.0))
                    useless = NULL;
                else if (SvPOK(sv)) {
                  /* perl4's way of mixing documentation and code
                     (before the invention of POD) was based on a
                     trick to mix nroff and perl code. The trick was
                     built upon these three nroff macros being used in
                     void context. The pink camel has the details in
                     the script wrapman near page 319. */
                    const char * const maybe_macro = SvPVX_const(sv);
                    if (strnEQ(maybe_macro, "di", 2) ||
                        strnEQ(maybe_macro, "ds", 2) ||
                        strnEQ(maybe_macro, "ig", 2))
                            useless = NULL;
                    else {
                        SV * const dsv = newSVpvs("");
                        useless_sv
                            = Perl_newSVpvf(aTHX_
                                            "a constant (%s)",
                                            pv_pretty(dsv, maybe_macro,
                                                      SvCUR(sv), 32, NULL, NULL,
                                                      PERL_PV_PRETTY_DUMP
                                                      | PERL_PV_ESCAPE_NOCLEAR
                                                      |
PERL_PV_ESCAPE_UNI_DETECT));
                        SvREFCNT_dec_NN(dsv);
                    }
                }
                else if (SvOK(sv)) {
                    useless_sv = Perl_newSVpvf(aTHX_ "a constant (%"SVf")", sv);
                }
                else
                    useless = "a constant (undef)";
            }

Not bothering to include a perl -v, this is tested on multiple
versions of perl from 5.14.2 on, and is still present in a relative
(max two weeks old) blead perl.

Yves


--
perl -Mre=debug -e "/just|another|perl|hacker/"


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About