...
These cases are recorded in Annex J, subclause J.2, items 110, 114, 122, 124, and 138. Programmers should never attempt to access anything underlying any of these macros.
Noncompliant Code Example (assert
)
In this example, the standard assert()
macro is suppressed in an attempt to pass it as a function pointer to the execute_handler()
function. Attempting to suppress the assert()
macro is undefined behavior.
Code Block | ||||
---|---|---|---|---|
| ||||
#include <assert.h> typedef void (*handler_type)(int); void execute_handler(handler_type handler, int value) { handler(value); } void func(int e) { execute_handler(&(assert), e < 0); } |
Compliant Solution (assert
)
In this compliant solution, the assert()
macro is wrapped in a helper function, removing the undefined behavior:
Code Block | ||||
---|---|---|---|---|
| ||||
#include <assert.h> typedef void (*handler_type)(int); void execute_handler(handler_type handler, int value) { handler(value); } static void assert_handler(int value) { assert(value); } void func(int e) { execute_handler(&assert_handler, e < 0); } |
Noncompliant Code Example (Redefining errno
)
Legacy code is apt to include an incorrect declaration, such as the following:
Code Block | ||||
---|---|---|---|---|
| ||||
extern int errno; |
Compliant Solution (Redefining errno
)
The correct way to declare errno
is to include the header <errno.h>
:
...
C-conforming implementations are required to declare errno
in <errno.h>
, although some historic implementations failed to do so.
Risk Assessment
Accessing objects or functions underlying these macros does not produce defined behavior, which may lead to incorrect or unexpected program behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC38-C | Low | Unlikely | Medium | P2 | L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Bibliography
ISO/IEC 9899:2011 | Subclause 7.1.4, "Use of Library Functions" |
...