\[[ISO/IEC 9899-1999|AA. References#ISO/IEC 9899-1999]\] enumerates several instances where the behavior of accessing the object or function expanded to be a standard library macro definition is [undefined |BB. Definitions#undefined behavior]. |
The macros are assert, errno, math_errhandling, setjmp, va_start, va_arg, va_copy, and va_end.
These cases are recorded in the list of undefined behavior , items 104 , 108 , 116 , 118 and 130 .
Programmers should never attempt to access anything underlying any of these macros.
In this example, a programmer working with a known <assert.h> is attempting to subvert the standard assert functionality so that assertions are always made, regardless of whether ndebug is set.
#include <assert.h>
#undef assert
void myassert(int e) {
__assert13(__FILE__, __LINE__, __assert_function__, e);
}
|
This call results in undefined behavior, so the programmer can now never rely on assertions, even in debug builds.
In this solution, the programmer does not #undef a standard macro, and explicitly handles any release-build assertion checks.
#include <assert.h>
void myassert(int e) {
assert(e);
/* other verification ... */
}
|
Legacy code is apt to include an incorrect declaration such as the following.
extern int errno; |
The correct way to declare errno is to include the header <errno.h>.
#include <errno.h> |
Implementations conforming to C99 are required to declare errno in <errno.h>, although some historic implementations failed to do so.
Accessing objects or function 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 |
\[[ISO/IEC 9899:1999|AA. References#ISO/IEC 9899-1999]\], all sections indicated by the [undefined behavior items |CC. Undefined Behavior] noted above. |
koders.com, <assert.h> source.