This standard recommends the inclusion of diagnostic tests into your program using the assert()
macro or other mechanisms (Assertions are a valuable diagnostic tool for finding and eliminating software defects that may result in vulnerabilities (see MSC11-A. Incorporate diagnostic tests using assertions). This facility enables assertions to be made at compile time rather than runtime, meeting the following requirements:
- All processing must be performed during compile time - no runtime cost in space or time is tolerable.
- Assertion failure must result in a meaningful and informative diagnostic error message.
- It can be used at file or block scope.
- Misuse does not result in silent malfunction but is diagnosed at compile time.
The run-time assert()
macro has some limitations, however, in that it occurs a run-time overhead and, because it calls abort()
, are only useful for identifying incorrect assumptions and not intended for runtime error checking. Consequently, run-time assertions are generally unsuitable for server programs or embedded systems.
Static assertion is also a new facility in the C++ 0X draft standard and Static assertions take the form
Code Block |
---|
static_assert(constant-expression, string-literal); |
In a static assert declarationAccording to the C++ 0X draft standard, the constant-expression
in a static assert declaration is a constant expression that can be converted to bool
at compile time. If the value of the expression when converted is true, the declaration has no effect. Otherwise the program is ill-formed, and a diagnostic message (which includes the text of the string-literal
) is issued at compile time. For example:
Code Block |
---|
static_assert(sizeof(int) <= sizeof(void*), "sizeof(int) <= sizeof(void*)"); /* Passes */ static_assert(sizeof(double) <= sizeof(int), "sizeof(double) <= sizeof(int)"); /* Fails */ |
Static assertion is also a new facility in the C++ 0X draft standardnot available in C99, but the facility is being considered for inclusion in C1X by the ISO/IEC WG14 international standardization working group.
Non-Compliant Code Example
...
The static_assert()
macro accepts a constant expression e
, which is evaluated as the first operand to the conditional operator. If e
evaluates to nonzero, an array type with a dimension of 1 is defined; otherwise an array type with a dimension of -1 is defined. Because it is invalid to declare an array with a negative dimension, the resulting type definition will be flagged by the compiler. The name of the array is used to indicate the location of the failed assertion.
The macro argument string-literal
is ignored in this case; this is meant for future compatibility.
Wiki Markup |
---|
The {{JOIN()}} macro used the {{\##}} operator \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] to concatenate tokens. See [PRE05-A. Understand macro replacement when concatenating tokens] to understand how macro replacement behaves in C when using the {{\##}} operator. |
Static assertions allow incorrect assumptions to be diagnosed at compile time, instead of resulting in a silent malfunction or run-time error. Because the assertion is performed at compile time, no run-time cost in space or time is incurred. An assertion can be used at file or block scope and failure results in a meaningful and informative diagnostic error message.
Risk Assessment
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
DCL03-A | 1 (low) | 1 (unlikely) | 1 (high) | P1 | L3 |
...
Wiki Markup |
---|
\[[Eckel 07|AA. C References#Eckel 07]\]
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.10.1, "Conditional inclusion," and Section 6.10.3.3, "The ## operator," and Section 7.2.1, "Program diagnostics"
\[[Klarer 04|AA. C References#Klarer 04]\]
\[[Saks 05|AA. C References#Saks 05]\]
\[[Saks 08|AA. C References#Saks 08]\] |
...