CertC-EXP07¶
Do not diminish the benefits of constants by assuming their values in expressions
Required inputs: IR
If a constant value is given for an identifier, do not diminish the maintainability of the code in which it is used by assuming its value in expressions. Simply giving the constant a name is not enough to ensure modifiability; you must be careful to always use the name, and remember that the value can change. This recommendation is related to DCL06-C. Use meaningful symbolic constants to represent literal values.
Noncompliant Code Example
The header
stdio.h defines the
BUFSIZ macro, which expands to an integer constant expression that
is the size of the buffer used by the
setbuf() function. This noncompliant code example defeats the
purpose of defining
BUFSIZ as a constant by assuming its value in the following
expression:
#include <stdio.h> /* ... */ nblocks = 1 + ((nbytes - 1) >> 9); /* BUFSIZ = 512 = 2^9 */
The programmer's assumption underlying this code is that "everyone knows that
BUFSIZ equals 512," and right-shifting 9 bits is the same (for
positive numbers) as dividing by 512. However, if
BUFSIZ changes to 1024 on some systems, modifications are
difficult and error prone.
Compliant Solution
This compliant solution uses the identifier assigned to the constant value in the expression:
#include <stdio.h> /* ... */ nblocks = 1 + (nbytes - 1) / BUFSIZ;
Most modern C compilers will optimize this code appropriately.
Risk Assessment
Assuming the value of an expression diminishes the maintainability of code and can produce unexpected behavior under any circumstances in which the constant changes.
| Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
| EXP07-C | Low | Unlikely | Medium | P2 | L3 |
Related Guidelines
| SEI CERT C++ Coding Standard | VOID EXP07-CPP. Do not diminish the benefits of constants by assuming their values in expressions |
Bibliography
| [ Plum 1985] | Rule 1-5 |
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
magic_number |
Use of magic literal. |
None |
False |
magic_number_without_token |
Use of magic literal. |
None |
False |
possible_magic_number |
Potential use of magic literal. |
None |
False |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
allow_nonconst_variable_initialization¶
allow_nonconst_variable_initialization : bool = False
allowed¶
allowed : set[float] = {0.0, 1.0, 2.0}
allowed_contexts¶
allowed_contexts : set[bauhaus.ir.PIR_Class_Name | typing.Callable[[bauhaus.ir.Node], bool]] = set()
exceptions¶
exceptions : typing.Callable[[bauhaus.ir.Node], bool] | None = None
exclude_pp_literals¶
exclude_pp_literals : bool = True
exclude_single_uses¶
exclude_single_uses : bool = False