You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 20 Next »

The C Standard [ISO/IEC 9899:2011] 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.

Noncompliant Code Example (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.

Compliant Solution (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
}

Noncompliant Code Example (Redefining errno)

Legacy code is apt to include an incorrect declaration, such as the following.

extern int errno;

Compliant Solution (Redefining 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.

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 Guidelines

ISO/IEC 9899:2011 Section 7.2, "Diagnostics <assert.h>," Section 7.5, "Errors <errno.h>," Section 7.12, "Mathematics <math.h>," Section 7.13 "Nonlocal jumps <setjmp.h>," and Section 7.16.1, "Variable argument list access macros"

 


  • No labels