Perl provides several mechanisms for warning the user about potential problems with the program. The use warnings
pragma turns on a default set of warnings for the Perl runtime to produce should it detect questionable code. The -w
command-line argument serves the same purpose. It is considered so useful that the perl(1)
manpage [Wall 2011] dryly notes the first bug in Perl is that :
...
"the -w
switch is not mandatory" [Wall 2011] .
The use warnings
pragma must be used in all Perl code.
...
However, occasionally there is a need to disable warnings or strictness for some code that may look strange , but is actually correct. The -w
switch cannot enable or disable particular warnings on particular ranges of code. When a particular warning or strict checking must be disabled, the no warnings
or no strict
pragmas should be used in as minimal a scope as possible. They should also disable the specific warning or strictness checker that would trigger a warning or fatal error , rather than disable all checks.
...
Code Block | ||||
---|---|---|---|---|
| ||||
use warnings;
use strict;
my %days = ("Sunday" => 'pray',
"Monday" => 'work',
"Tuesday" => 'work',
"Wednesday" => 'work',
"Thursday" => 'work',
"Friday" => 'work',
"Saturday" => 'rest');
sub what_to_do {
my $day = shift;
if ($days{$day} eq 'work') {
return 'work hard';
}
if (exists $days{$day}) {
return $days{$day};
} else {
return "do nothing";
}
}
my $task = what_to_do('tomorrow');
print "Prepare to $task\n";
|
This code produces the following output:
Code Block |
---|
Use of uninitialized value within %days in string eq at ./example.pl line 16.
Prepare to do nothing
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
use warnings;
use strict;
no warnings 'uninitialized';
my %days = ("Sunday" => 'pray',
# ...
|
Unfortunately while , although this does code correctly suppress suppresses the warning message, it has the undesired effect of suppressing the warning message throughout the entire program . This has the likely effect of suppressing and will likely suppress the warning in other lines of code that are not known to be correct.
...
Code Block | ||||
---|---|---|---|---|
| ||||
sub what_to_do {
my $day = shift;
no warnings 'uninitialized';
if ($days{$day} eq 'work') {
return 'work hard';
}
if (exists $days{$day}) {
return $days{$day};
} else {
return "do nothing";
}
}
|
...
Code Block | ||||
---|---|---|---|---|
| ||||
use strict;
use warnings;
our $sunday = 'pray';
our $monday = 'work';
our $tuesday = 'work';
our $wednesday = 'work';
our $thursday = 'work';
our $friday = 'work';
our $saturday = 'rest';
sub what_to_do {
my $day = shift;
no warnings 'uninitialized';
if ($$day eq 'work') {
return 'work hard';
}
if (defined $$day) {
return $$day;
} else {
return "do nothing";
}
}
my $task = what_to_do('tomorrow');
print "Prepare to $task\n";
|
The strict
pragma catches the improper reference and aborts the program, producing the following error message:
Code Block |
---|
Can't use string ("tomorrow") as a SCALAR ref while "strict refs" in use at ./example.pl line 19.
|
...
This noncompliant code example disables the strict
pragma, thus producing proper output. However, strict-ness strictness is suppressed throughout the entire program.
Code Block | ||||
---|---|---|---|---|
| ||||
use warnings;
use strict;
no strict 'refs';
our $sunday = 'pray';
# ...
|
This code produces the following output:
Code Block |
---|
Prepare to do nothing
|
This example may be considered correct, but the code works by referencing a nonexistent variable $tomorrow
.
...
This compliant solution suppresses the strict-ness strictness checking to as minimal a scope as possible. Because the strict strictness checking is suppressed only inside the what_to_do
subroutine, other regions of the code can still be checked for strict compliance.
Code Block | ||||
---|---|---|---|---|
| ||||
sub what_to_do {
my $day = shift;
no warnings 'uninitialized';
no strict 'refs';
if ($$day eq 'work') {
return 'work hard';
}
if (defined $$day) {
return $$day;
} else {
return "do nothing";
}
}
|
...
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC02-PL | low Low | unlikely Unlikely | medium Medium | P2 | L2 |
Related Guidelines
CERT C Secure Coding Standard: MSC00-C. Compile cleanly at high warning levels
CERT C++ Secure Coding Standard: MSC00-CPP. Compile cleanly at high warning levels
L3 |
Automated Detection
Tool | Diagnostic |
---|---|
Perl::Critic | TestingAndDebugging::ProhibitNoStrict |
Perl::Critic | TestingAndDebugging:;ProhibitNoWarnings |
Perl::Critic | TestingAndDebugging::ProhibitProlongedStrictureOverride |
Perl::Critic | TestingAndDebugging::RequireUseStrict |
Related Guidelines
SEI CERT C Coding Standard | MSC00-C. Compile cleanly at high warning levels |
---|---|
SEI CERT C++ Coding Standard | VOID MSC00-CPP. Compile cleanly at high warning levels |
Bibliography
...
2005] | "Overriding Strictures," p |
---|
...
...
EXP30-PL. Do not use deprecated or obsolete functions 02. Expressions