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, a programmer attempts to access his own verification functionality by suppressing the assert macro and instead sending control to 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 <myassert.h>
#include <assert.h>
void fullAssert(int e) {
assert(0 < e); // Invoke standard library assert()
(assert)(0 < e); // assert() macro suppressed, calling function assert()
}
|
Having this function and attempting to access it produces undefined behavior.
assert)The programmer should place nonstandard verification in a function that does not conflict with the standard library macro assert—for example, myassert().
#include <myassert.h>
#include <assert.h>
void fullAssert(int e) {
assert(0 < e); // Standard library assert()
myassert(e); // 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 |