Perl provides several mechanisms for warning the user about potential problems with the program. The {{ Wiki Markup 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|AA. Bibliography#Manpages]\] 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 |
Bibliography
...
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
[Conway 2005] | "Overriding Strictures," p. 433 |
---|---|
[CPAN] | Elliot Shank, Perl-Critic-1.116 |
...
...
...
, TestingAndDebugging::ProhibitProlongedStrictureOverride, TestingAndDebugging::RequireUseStrict | |
[Wall 2011] | perl strict warnings |
...
|http://search.cpan.org/dist/Perl-Critic/lib/Perl/Critic/Policy/TestingAndDebugging/ProhibitProlongedStrictureOverride.pm], [TestingAndDebugging::RequireUseStrict|http://search.cpan.org/dist/Perl-Critic/lib/Perl/Critic/Policy/TestingAndDebugging/RequireUseStrict.pm] \[[Wall 2011|AA. Bibliography#Manpages]\] [perl|http://perldoc.perl.org/perl.html] [strict|http://perldoc.perl.org/strict.html] [warnings|http://perldoc.perl.org/warnings.html]EXP30-PL. Do not use deprecated or obsolete functions 02. Expressions