Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'Useless use of a constant in void context' is compile-time but not syntax warning #14442

Closed
p5pRT opened this issue Jan 24, 2015 · 20 comments
Closed

Comments

@p5pRT
Copy link

p5pRT commented Jan 24, 2015

Migrated from rt.perl.org#123665 (status was 'open')

Searchable as RT123665$

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

From @epa

Created by @epa

This program warns 'Useless use of a constant ("a") in void context'​:

#!/usr/bin/perl
use strict;
use warnings;
use 5.018;
use warnings FATAL => 'syntax';
sub x { 'a'; return 0 }
say 'ok';

Since x() is never called the warning must be compile time. Yet
it is not made FATAL.

Now it is not really a syntax error, more a semantic check, so I can
see how it is not included as 'syntax'. I would like to make all
compilation warnings fatal without making run-time warnings fatal.
Perhaps that could be done using a BEGIN block and so on. Could
that feature be added to warnings.pm, as

  use warnings FATAL => 'compilation';

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.18.4:

Configured by Red Hat, Inc. at Thu Oct 30 14:55:21 UTC 2014.

Summary of my perl5 (revision 5 version 18 subversion 4) configuration:

  Platform:
    osname=linux, osvers=3.16.3-200.fc20.x86_64, archname=x86_64-linux-thread-multi
    uname='linux buildvm-18.phx2.fedoraproject.org 3.16.3-200.fc20.x86_64 #1 smp wed sep 17 22:34:21 utc 2014 x86_64 x86_64 x86_64 gnulinux '
    config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches  -m64 -mtune=generic -Dccdlflags=-Wl,--enable-new-dtags -Dlddlflags=-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches  -m64 -mtune=generic -Wl,-z,relro  -Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.18.4 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin -Dusesitecustomize'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.8.3 20140911 (Red Hat 4.8.3-7)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -fstack-protector'
    libpth=/usr/local/lib64 /lib64 /usr/lib64
    libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc -lgdbm_compat
    perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.18'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -Wl,-z,relro '

Locally applied patches:
    Fedora Patch1: Removes date check, Fedora/RHEL specific
    Fedora Patch3: support for libdir64
    Fedora Patch4: use libresolv instead of libbind
    Fedora Patch5: USE_MM_LD_RUN_PATH
    Fedora Patch6: Skip hostname tests, due to builders not being network capable
    Fedora Patch7: Dont run one io test due to random builder failures
    Fedora Patch9: Fix find2perl to translate ? glob properly (RT#113054)
    Fedora Patch10: Update h2ph(1) documentation (RT#117647)
    Fedora Patch11: Update pod2html(1) documentation (RT#117623)
    Fedora Patch12: Disable ornaments on perl5db AutoTrace tests (RT#118817)
    Fedora Patch14: Do not use system Term::ReadLine::Gnu in tests (RT#118821)
    Fedora Patch15: Define SONAME for libperl.so
    Fedora Patch16: Install libperl.so to -Dshrpdir value
    Fedora Patch18: Fix crash with \\&$glob_copy (RT#119051)
    Fedora Patch19: Fix coreamp.t rand test (RT#118237)
    Fedora Patch20: Reap child in case where exception has been thrown (RT#114722)
    Fedora Patch21: Fix using regular expressions containing multiple code blocks (RT#117917)
    Fedora Patch22: Create site paths by cpan for the first time (CPAN RT#99905)
    Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux
    Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux


@INC for perl 5.18.4:
    /home/eda/lib/perl5/
    /usr/local/lib64/perl5
    /usr/local/share/perl5
    /usr/lib64/perl5/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib64/perl5
    /usr/share/perl5
    .


Environment for perl 5.18.4:
    HOME=/home/eda
    LANG=en_GB.UTF-8
    LANGUAGE (unset)
    LC_COLLATE=C
    LC_CTYPE=en_GB.UTF-8
    LC_MESSAGES=en_GB.UTF-8
    LC_MONETARY=en_GB.UTF-8
    LC_NUMERIC=en_GB.UTF-8
    LC_TIME=en_GB.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/eda/bin:/home/eda/bin:/usr/local/bin:/usr/bin:/sbin:/usr/sbin:/sbin:/usr/sbin
    PERL5LIB=/home/eda/lib/perl5/
    PERL_BADLANG (unset)
    SHELL=/bin/bash


______________________________________________________________________
This email has been scanned by the Symantec Email Security.cloud service.
For more information please visit http://www.symanteccloud.com
______________________________________________________________________

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

From @jkeenan

On Sat Jan 24 00​:06​:21 2015, eda@​waniasset.com wrote​:

This is a bug report for perl from eda@​waniasset.com,
generated with the help of perlbug 1.39 running under perl 5.18.4.

-----------------------------------------------------------------
[Please describe your issue here]

This program warns 'Useless use of a constant ("a") in void context'​:

#!/usr/bin/perl
use strict;
use warnings;
use 5.018;
use warnings FATAL => 'syntax';
sub x { 'a'; return 0 }
say 'ok';

Since x() is never called the warning must be compile time. Yet
it is not made FATAL.

Now it is not really a syntax error, more a semantic check, so I can
see how it is not included as 'syntax'. I would like to make all
compilation warnings fatal without making run-time warnings fatal.
Perhaps that could be done using a BEGIN block and so on. Could
that feature be added to warnings.pm, as

use warnings FATAL => 'compilation';

There is no bug here. You are using the wrong category of warnings. The case you describe is covered by category 'void', not category 'syntax'. See​: 'perldoc perldiag'.

#####
$ perl -v | head -2 | tail -1
This is perl 5, version 18, subversion 4 (v5.18.4) built for x86_64-linux

$ perl -Mstrict -E 'use warnings FATAL => q{syntax}; sub x { q{a}; return 0 } say q{ok};'
ok

$ perl -Mstrict -E 'use warnings FATAL => q{void}; sub x { q{a}; return 0 } say q{ok};'
Useless use of a constant ("a") in void context at -e line 1.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

@jkeenan - Status changed from 'open' to 'rejected'

@p5pRT p5pRT closed this as completed Jan 24, 2015
@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

From @epa

If the program has

use warnings FATAL => q{void};

then it can compile but later die at run time when a particular line of code is reached.
I don't want that. But I would like to get an error for the 'void' warnings that can be detected at compile time.
Is that possible?

______________________________________________________________________
This email has been scanned by the Symantec Email Security.cloud service.
For more information please visit http​://www.symanteccloud.com
______________________________________________________________________

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

From Eirik-Berg.Hanssen@allverden.no

On Sat, Jan 24, 2015 at 3​:43 PM, James E Keenan via RT <
perlbug-followup@​perl.org> wrote​:

I would like to make all
compilation warnings fatal without making run-time warnings fatal.
Perhaps that could be done using a BEGIN block and so on. Could
that feature be added to warnings.pm, as

use warnings FATAL => 'compilation';

There is no bug here. You are using the wrong category of warnings. The
case you describe is covered by category 'void', not category 'syntax'.

  It's not a bug report, but it is a feature request. A wishlist item.

  ... with an unfortunate subject, but still ...

  Seriously, how would one make all compile-time warnings fatal, but leave
run-time warnings nonfatal?

Eirik

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

@jkeenan - Status changed from 'rejected' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

From @haarg

This isn't correct. Enabling fatal void warnings will cause the code
to die at compile time, not runtime.

On Sat, Jan 24, 2015 at 10​:15 AM, Ed Avis <eda@​waniasset.com> wrote​:

If the program has

use warnings FATAL => q{void};

then it can compile but later die at run time when a particular line of code is reached.
I don't want that. But I would like to get an error for the 'void' warnings that can be detected at compile time.
Is that possible?

______________________________________________________________________
This email has been scanned by the Symantec Email Security.cloud service.
For more information please visit http​://www.symanteccloud.com
______________________________________________________________________

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

From @epa

Graham Knop <haarg <at> haarg.org> writes​:

Enabling fatal void warnings will cause the code
to die at compile time, not runtime.

Thanks. For some reason I thought this was not the case and that there
were some examples where the check happened at run time (not counting
eval and other tricks). But that could be just because I confused myself
thinking that all compile-time checks belonged under 'syntax'.

I guess then I just need use warnings FATAL => qw(syntax void) to do
what I want. Unless there are further compile-time warnings not
included in that?

--
Ed Avis <eda@​waniasset.com>

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2015

From Eirik-Berg.Hanssen@allverden.no

On Sat, Jan 24, 2015 at 9​:20 PM, Ed Avis <eda@​waniasset.com> wrote​:

I guess then I just need use warnings FATAL => qw(syntax void) to do
what I want. Unless there are further compile-time warnings not
included in that?

  Oh, there's more.

  What's more, among "misc" warnings, some are compile-time, and some are
run-time​:

$ perl -Mwarnings=misc -E 'BEGIN { say "<compiletime>" } say "<runtime>";
our($x); our $x; %x = @​ARGV; say "</runtime>"; BEGIN { say "</compiletime>"
}' 1
<compiletime>
"our" variable $x redeclared at -e line 1.
</compiletime>
<runtime>
Odd number of elements in hash assignment at -e line 1.
</runtime>
$

  So, how to fatalize only the one? I have no clue.

Eirik

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2015

From @cpansprout

On Sat Jan 24 12​:55​:36 2015, Eirik-Berg.Hanssen@​allverden.no wrote​:

On Sat, Jan 24, 2015 at 9​:20 PM, Ed Avis <eda@​waniasset.com> wrote​:

I guess then I just need use warnings FATAL => qw(syntax void) to do
what I want. Unless there are further compile-time warnings not
included in that?

Oh, there's more.

What's more, among "misc" warnings, some are compile-time, and some are
run-time​:

$ perl -Mwarnings=misc -E 'BEGIN { say "<compiletime>" } say "<runtime>";
our($x); our $x; %x = @​ARGV; say "</runtime>"; BEGIN { say "</compiletime>"
}' 1
<compiletime>
"our" variable $x redeclared at -e line 1.
</compiletime>
<runtime>
Odd number of elements in hash assignment at -e line 1.
</runtime>
$

So, how to fatalize only the one? I have no clue.

Hmmm. With current perl, you can do something like this​:

BEGIN { $SIG{__WARN__} = sub { die shift } }
...
BEGIN { undef $SIG{__WARN__} }

But that clobbers any existing handler.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2015

From @cpansprout

On Sat Jan 24 17​:30​:25 2015, sprout wrote​:

On Sat Jan 24 12​:55​:36 2015, Eirik-Berg.Hanssen@​allverden.no wrote​:

On Sat, Jan 24, 2015 at 9​:20 PM, Ed Avis <eda@​waniasset.com> wrote​:

I guess then I just need use warnings FATAL => qw(syntax void) to
do
what I want. Unless there are further compile-time warnings not
included in that?

Oh, there's more.

What's more, among "misc" warnings, some are compile-time, and some
are
run-time​:

$ perl -Mwarnings=misc -E 'BEGIN { say "<compiletime>" } say
"<runtime>";
our($x); our $x; %x = @​ARGV; say "</runtime>"; BEGIN { say
"</compiletime>"
}' 1
<compiletime>
"our" variable $x redeclared at -e line 1.
</compiletime>
<runtime>
Odd number of elements in hash assignment at -e line 1.
</runtime>
$

So, how to fatalize only the one? I have no clue.

Hmmm. With current perl, you can do something like this​:

BEGIN { $SIG{__WARN__} = sub { die shift } }
...
BEGIN { undef $SIG{__WARN__} }

But that clobbers any existing handler.

The thing is, warnings.pm is lexical, and this compile-time/run-time distinction is orthogonal to lexical scoping. I don‘t see how we could shoehorn the feature cleanly into warnings.pm. (Having $^W and warnings.pm already makes things undesirably complex. You can’t please everybody.)

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2015

From @epa

Father Chrysostomos via RT <perlbug-followup <at> perl.org> writes​:

The thing is, warnings.pm is lexical, and this compile-time/run-time
distinction is orthogonal to lexical scoping.

It is orthogonal; but equally the other distinctions supported by
warnings.pm ('void', 'syntax', etc) are orthogonal to scoping.

I expect that every warning currently issued by perl can be categorized
as either compile-time or run-time (ignoring the question of eval(), which
can convert a compile-time warning to a run-time one, and constant folding,
which may do the opposite).

(If I'm wrong and there are warnings which can fire at either stage, the
picture gets a bit more complicated. But assuming not...)

Then use warnings FATAL => 'compile-time' would turn on all warnings
categorized as compile-time warnings. This would effectively be syntactic
sugar for qw(void syntax etc).

The advantage is that the programmer wouldn't have to remember the exact
incantation to list all compile-time warnings and no run-time ones (and that
new compile-time warnings in later perl versions would automatically be
added to the list).

(There has often been discussion on p5p of the dangers of fatal warnings.
I could expand on the reasons why I believe that fatal compile-time warnings
are a useful tool while still wanting to avoid going kaboom at run time.)

--
Ed Avis <eda@​waniasset.com>

@p5pRT
Copy link
Author

p5pRT commented Jan 25, 2015

From @haarg

On Sun, Jan 25, 2015 at 1​:11 PM, Ed Avis <eda@​waniasset.com> wrote​:

It is orthogonal; but equally the other distinctions supported by
warnings.pm ('void', 'syntax', etc) are orthogonal to scoping.

I expect that every warning currently issued by perl can be categorized
as either compile-time or run-time (ignoring the question of eval(), which
can convert a compile-time warning to a run-time one, and constant folding,
which may do the opposite).

If you are speaking of the individual warnings, probably. But if you
are talking about categories this isn't the case.

(If I'm wrong and there are warnings which can fire at either stage, the
picture gets a bit more complicated. But assuming not...)

Then use warnings FATAL => 'compile-time' would turn on all warnings
categorized as compile-time warnings. This would effectively be syntactic
sugar for qw(void syntax etc).

The advantage is that the programmer wouldn't have to remember the exact
incantation to list all compile-time warnings and no run-time ones (and that
new compile-time warnings in later perl versions would automatically be
added to the list).

There currently is no incantation you can use to only get compile time warnings.

For my favorite example of this, the exec category has two warnings.
The first is compile time, warning about having code after an exec
call, because the code will never be reached. The second is a runtime
warning for if the exec call fails, such as the file given not
existing. This also impacts system. Normally with system, if the
exec call fails it will issue a warning and then exit the sub process.
The extra fun bit though is that with fatal warnings, the warning is
thrown as an error and the exit isn't reached. If that fatalized
warning is caught with an eval, you now have two processes running
where you thought you only had one.

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2015

From @epa

Yes, I meant that each individual warning is either compile-time or run-time.
A category which gathers up all compile-time warnings would be orthogonal to the existing categories.
At first I assumed that 'syntax' collected all compile-time checks, but that is not the case.

______________________________________________________________________
This email has been scanned by the Symantec Email Security.cloud service.
For more information please visit http​://www.symanteccloud.com
______________________________________________________________________

@p5pRT
Copy link
Author

p5pRT commented Sep 14, 2016

From arisadam25@mail.com

The functions in this section can serve as terms in an expression.
  They fall into two major categories​: list operators and named unary
  operators. These differ in their precedence relationship with a fol-
  lowing comma.
There are two issues at hand here.

  Why does use bigint; 1; warn in void context?
  Why is the constant being executed in void context in the first place?

$ perl -c -we'1 while sub_with_side_effects();'
-e syntax OK

$ perl -c -we'use bigint; 1 while sub_with_side_effects();'
Useless use of a constant (1) in void context at -e line 1.
-e syntax OK

OK, so - from the comments - you're comparing two arrays.

Presumably inside your loop you're doing something like​:

if ( $name[$j] == $name_mod[$k] ) {

So my suggestion would be - don't do it like that​:

for ( my $index = 0; $index < @​name and $index < @​name_mod; $index++ ) {
  if ( $name[$index] == $name_mod[$index] ) {
  #do something
  }
}

Or perhaps​: each_array

my $ea = each_array(@​name, @​name_mod);
while ( my ($cur_name, $cur_name_mod ) = $ea->() ) { .... }

@p5pRT
Copy link
Author

p5pRT commented Sep 14, 2016

From [Unknown Contact. See original ticket]

The functions in this section can serve as terms in an expression.
  They fall into two major categories​: list operators and named unary
  operators. These differ in their precedence relationship with a fol-
  lowing comma.
There are two issues at hand here.

  Why does use bigint; 1; warn in void context?
  Why is the constant being executed in void context in the first place?

$ perl -c -we'1 while sub_with_side_effects();'
-e syntax OK

$ perl -c -we'use bigint; 1 while sub_with_side_effects();'
Useless use of a constant (1) in void context at -e line 1.
-e syntax OK

OK, so - from the comments - you're comparing two arrays.

Presumably inside your loop you're doing something like​:

if ( $name[$j] == $name_mod[$k] ) {

So my suggestion would be - don't do it like that​:

for ( my $index = 0; $index < @​name and $index < @​name_mod; $index++ ) {
  if ( $name[$index] == $name_mod[$index] ) {
  #do something
  }
}

Or perhaps​: each_array

my $ea = each_array(@​name, @​name_mod);
while ( my ($cur_name, $cur_name_mod ) = $ea->() ) { .... }

@p5pRT
Copy link
Author

p5pRT commented Sep 15, 2016

From @Abigail

On Wed, Sep 14, 2016 at 05​:37​:43AM -0700, Redfred Garett via RT wrote​:

The functions in this section can serve as terms in an expression.
They fall into two major categories​: list operators and named unary
operators. These differ in their precedence relationship with a fol-
lowing comma.
There are two issues at hand here.

Why does use bigint; 1; warn in void context?
Why is the constant being executed in void context in the first place?

$ perl -c -we'1 while sub_with_side_effects();'
-e syntax OK

$ perl -c -we'use bigint; 1 while sub_with_side_effects();'
Useless use of a constant (1) in void context at -e line 1.
-e syntax OK

The answer to the second question is simple​: it's executed in void
context because that's how the program is written. The body of the
while loop is just '1', which is in void context.

As for the first part​: Normally, perl warns if it sees a literal in
void context. The assumption is that this is likely to be a bug, as
there would not be any effect. However, exceptions are made for the
values 1 and 0 -- that allows you to write things like "1 while ..."
without perl complaining.

However, under "use bigint", what looks like a literal 1 to the reader
no longer looks like a plain literal to perl. It's an overloaded
Math​::BigInt object. It's no longer a literal, and perl doesn't know
whether fechting the value has any side effects or not. So, it won't
warn.

To see the difference​:

  $ perl -MDevel​::Peel -we 'Dump 1';
  SV = IV(0x1008035e8) at 0x1008035f8
  REFCNT = 1
  FLAGS = (IOK,READONLY,PROTECT,pIOK)
  IV = 1

  $ perl -MDevel​::Peel -we 'use bigint; Dump 1';
  SV = IV(0x1009559d0) at 0x1009559e0
  REFCNT = 1
  FLAGS = (ROK,READONLY,PROTECT)
  RV = 0x101000450
  SV = PVHV(0x1008ac840) at 0x101000450
  REFCNT = 1
  FLAGS = (OBJECT,SHAREKEYS)
  STASH = 0x101044288 "Math​::BigInt"
  ARRAY = 0x10061f870 (0​:6, 1​:2)
  hash quality = 125.0%
  KEYS = 2
  FILL = 2
  MAX = 7
  Elt "sign" HASH = 0xdd7ff9fd
  SV = PV(0x100805f80) at 0x10082bdf8
  REFCNT = 1
  FLAGS = (POK,IsCOW,pPOK)
  PV = 0x100714b00 "+"\0
  CUR = 1
  LEN = 10
  COW_REFCNT = 1
  Elt "value" HASH = 0x7fda65e6
  SV = IV(0x101000410) at 0x101000420
  REFCNT = 1
  FLAGS = (ROK)
  RV = 0x10082bdb0
  SV = PVAV(0x1008060c8) at 0x10082bdb0
  REFCNT = 1
  FLAGS = ()
  ARRAY = 0x1006239c0
  FILL = 0
  MAX = 0
  ARYLEN = 0x0
  FLAGS = (REAL)

Regards,

Abigail
  Elt No. 0
  SV = IV(0x10082bd88) at 0x10082bd98
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1

@p5pRT
Copy link
Author

p5pRT commented Sep 15, 2016

From Eirik-Berg.Hanssen@allverden.no

On Thu, Sep 15, 2016 at 11​:10 AM, Abigail <abigail@​abigail.be> wrote​:

Why does use bigint; 1; warn in void context?

[snip]

However, under "use bigint", what looks like a literal 1 to the reader
no longer looks like a plain literal to perl. It's an overloaded
Math​::BigInt object. It's no longer a literal, and perl doesn't know
whether fechting the value has any side effects or not. So, it won't
warn.

  Um, that's just the thing – it does warn​:

$ perl -we 'use bigint; 1'
Useless use of a constant (1) in void context at -e line 1.
$

  Compare​:

$ perl -we '1;' -e '2;' -e 'use bigint; 1;' -e2
Useless use of a constant (2) in void context at -e line 2.
Useless use of a constant (1) in void context at -e line 3.
Useless use of a constant (2) in void context at -e line 4.
$

  The missing warning from the first literal is, as you said, the special
case for 0 and 1.

  The warning from the penultimate literal shows that the special case for
0 and 1 does not apply when the literals are overloaded.

  Moreover, the warning from either of the last two literals also shows
that perl indeed warns, even if might not "know whether fetching the value
has any side effect or not".

  I'm not saying perl is doing the wrong thing in general to warn for
overloaded literals in void context – I'll leave that for you guys, just
noting that it does – but as long as I'm writing, I'd say it would be
_nice_ if at least the special case (the lack of warning for 0 and 1 in
void context) could be retained also when literals are overloaded. Not
that I'm expecting it to be easy though.

Eirik

@epa
Copy link
Contributor

epa commented Mar 9, 2020

Could I ask whoever triages bugs to have another look at this one? It seems to have got a bit jumbled up with comments from an unrelated bug about bigint added to the end. I believe that my comment on 2015-01-26 is the last one that belongs and the others can be moved to a new bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants