| Wiki Markup |
|---|
Enforcing invariants such as object immutability using existing language mechanisms{{const}}\-qualification helps ensures the correctness and security of applications. For example, ISO/IEC PDTR 24772 \[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] recommends labeling parameters as constant to avoid the unintentional modification of function arguments. |
...
This recommendation is related to EXP07-A. Do not diminish the benefits of constants by assuming their values in expressions.
Non-Compliant Code Example (Object-Like Macro)
A preprocessing directive of the form:
...
| Code Block | ||
|---|---|---|
| ||
#define PI 3.14159f float degrees; float radians; /* ... */ radians = degrees * PI / 180; |
Compliant Solution
In this compliant solution, pi is declared as a const-qualified object, allowing the constant to have scope and to have its value inspected by a debugger.
...
While inadequate in some ways, this is the best that can be done for non-integer constants.
Non-Compliant Code Example (Immutable Integer Values)
In this non-compliant code example, max is declared as a const-qualified object. While declaring non-integer constants as const-qualified objects is the best that can be done in C, for integer constants we can do better. Declaring immutable integer values as const-qualified objects still allows the programmer to take the address of the object. Also, const-qualified integers cannot be used in locations where an integer constant is required, such as the value of a case constant.
...
Most C compilers allocate memory for const-qualified objects.
Compliant Solution (enum)
This compliant solution declares max as an enumeration constant rather than a const-qualified object or a macro definition.
| Code Block | ||
|---|---|---|
| ||
enum { max = 15 };
int a[max]; /* OK */
const int *p;
p = &max; /* error: '&' on constant */
|
Exceptions
DCL00-EX1 Constant values that may be passed as compile-time arguments must be macro definitions, as shown by this example:
| Code Block |
|---|
#ifndef MYPORTNUMBER /* might be passed on compile line */ # define MYPORTNUMBER 1234 #endif |
Risk Assessment
Using ordinary variables to hold constants instead of using enumeration constants or const-qualified objects can result in a value intended to be constant being changed at runtime.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
DCL00-A | 1 (low) | 1 (unlikely) | 2 (medium) | P2 | L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
| Wiki Markup |
|---|
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.3.2.1, "Lvalues, arrays, and function designators," Section 6.7.2.2, "Enumeration specifiers," and Section 6.10.3, "Macro replacement" \[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "CSJ Passing parameters and return values" \[[Saks 00|AA. C References#Saks 00]\] Dan Saks. [Numeric Literals|http://www.embedded.com/2000/0009/0009pp.htm]. Embedded Systems Programming. September, 2000. \[[Summit 05|AA. C References#Summit 05]\] [Question 10.5b|http://c-faq.com/cpp/constvsdefine.html] |
...