Why does Perl warn about "useless constant 1" when using bigint?
Asked Answered
B

3

8

I was writing a module as part of my application when I noticed syntax check results in warning about useless use of a constant (1). Why is that?

The constant is the obligatory 1 at the end of the module which is normally ignored by warnings as perldoc perldiag says:

This warning will not be issued for numerical constants equal to 0 or 1 since they are often used in statements like

1 while sub_with_side_effects();

(There's probably an even better source for that. After all 1 at the end of files is totally desired and not to be warned about.)

But the warning is generated even for nearly empty modules if they use bigint.

package Foo;

use bigint;

1;

For this simple file syntax check produces the following warning:

$> perl -Wc Foo.pm
Useless use of a constant (1) in void context at Foo.pm line 5.
Foo.pm syntax OK

I could not find any reference to bigint and the warning message except Put long hex numbers in sqlite but this doesn't really address my issue, I think.

My Perl is v5.14.4 on Cygwin with bigint 0.36.

Bigoted answered 28/1, 2015 at 18:31 Comment(2)
Sounds like a bug.Parthenopaeus
Interesting find. I would guess it's because it's no longer '1' and thus ignorable, and is instead a special sort of '1'.Lindner
L
8

There are two issues at hand here.

  1. Why does use bigint; 1; warn in void context?
  2. 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

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

use bigint; installs a callback that's called when a constant literal is encountered by the parser, and the value returned by the callback is used as the constant instead. As such, under use bigint;, 1 is no longer truly just a simple 0 or 1.

But you're not doing anything wrong, so this warning is spurious. You can work around it by using () or undef instead of 1.

undef while sub_with_side_effects();

Unless I needed to use it throughout my code base, I would favour the following:

while ( sub_with_side_effects() ) { }

$ cat Module.pm
package Module;
use bigint;
1;

$ perl -c -w Module.pm
Useless use of a constant (1) in void context at Module.pm line 3.
Module.pm syntax OK

Why is the constant being executed in void context?

When Perl executes a module, Perl expects the module to return a scalar value, so Perl should be executing the module in scalar context.

However, you told Perl to compile the script Module.pm. When Perl executes a script, Perl doesn't require any values to be returned, so Perl executes the script in void context.

Using a module as a script can cause spurious warnings and errors, and so can passing -W. Test a module using as follows:

perl -we'use Module'

Actually, you shouldn't even need -w since you should already have use warnings; in the module. All you really need is

perl -e'use Module'
Landwaiter answered 28/1, 2015 at 20:44 Comment(0)
Q
6

-W instead of use warnings; in your module or checking modules with -c instead of perl -MFoo -e0 can show spurious errors. This is an example of the latter.

When you load a module normally, it isn't in void context, because it is checking that the result is true.

(Note that when I try it using 5.20.1, the -W also results in a spurious overload arg '..' is invalid at /usr/share/perl/5.20/Math/BigInt.pm line 155.)

Quincentenary answered 28/1, 2015 at 20:1 Comment(4)
Ironically, perl -MFoo -we0 fails when testing bigint. perl -we'use bigint;' does the same without warning.Landwaiter
ah, you mean -Mbigint; yes, that is ironic. perl -MFoo -we# worksQuincentenary
Boggle ... real bugs, buglets or QA issue ??Galvan
@G.Cito: no, there is no bug hereQuincentenary
B
0

Just leaving here a workaround to avoid the warning: Defining a constant with value 1 before using bigint:

package Foo;
use strict;
use warnings;
use constant PACKAGE_END => 1;
use bigint;

PACKAGE_END;
Beitch answered 12/4, 2019 at 12:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.