If a constant value is given for an identifier, do not diminish the modifiability of the code in which it is used by assuming its value in expressions. Just 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 could change. This recommendation is related to DCL06-A. Use meaningful symbolic constants to represent literal values in program logic.
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 non-compliant 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 nine 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.
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.
Hardwiring constants renders code potentially nonportable; in fact it will produce unexpected under any circumstances in which the constant changes.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
EXP07-A |
1 (low) |
1 (unlikely) |
2 (medium) |
P2 |
L3 |
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
\[[Plum 85|AA. C References#Plum 85]\] Rule 1-5 \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.10, "Preprocessing directives," and Section 5.1.1, "Translation environment" |
EXP06-A. Operands to the sizeof operator should not contain side effects 03. Expressions (EXP) EXP08-A. Ensure pointer arithmetic is used correctly