The C Standard enumerates several instances where the behavior of accessing an object or function expanded to be a standard library macro definition is undefined.
The macros are assert, errno, math_errhandling, setjmp, va_start, va_arg, va_copy, and va_end.
These cases are recorded in Annex J, section J.2, Undefined behavior, items 110, 114, 122, 124, and 138 [ISO/IEC 9899:2011].
Programmers should never attempt to access anything underlying any of these macros.
assert)In this example, the standard assert() macro is suppressed in favor of calling a user-defined assert() function.
Suppose the custom <myassert.h> declares a function assert() that does nonstandard verification, and the standard <assert.h> defines an assert macro as required by the standard:
#include <assert.h>
#include "myassert.h"
void fullAssert(int e) {
assert(e > 0); // Invoke standard library assert()
(assert)(e > 0); // assert() macro suppressed, calling function assert()
}
|
Having this function and attempting to access it produces undefined behavior. It is also a violation of DCL37-C. Do not declare or define a reserved identifier.
assert)The programmer should place nonstandard verification in a function that does not conflict with the standard library macro assert—for example, myassert():
#include <assert.h>
#include "myassert.h"
void fullAssert(int e) {
assert(e > 0); // Standard library assert()
myassert(e > 0); // Well-defined custom assertion function
}
|
errno)Legacy code is apt to include an incorrect declaration, such as the following:
extern int errno; |
errno)The correct way to declare errno is to include the header <errno.h>:
#include <errno.h> |
C-conforming implementations are required to declare errno in <errno.h>, although some historic implementations failed to do so.
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 |
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
| CERT C Secure Coding Standard | DCL37-C. Do not declare or define a reserved identifier |
| [ISO/IEC 9899:2011] | Annex J, subclause J.2, "Undefined behavior" |