Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Updated references from C11->C23

...

...

Any function declared in a header may be additionally implemented as a function-like macro defined in the header, so if a library function is declared explicitly when its header is included, one of the techniques shown later in the next subclause can be used to ensure the declaration is not affected by such a macro. Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses, because the name is then not followed by the left parenthesis that indicates expansion of a macro function name. For the same syntactic reason, it is permitted to take the address of a library function even if it is also defined as a macro. 220) The use of #undef to remove any macro definition will also ensure that an actual function is referred to.

220)This means that an implementation is required to provide an actual function for each library function, even if it also provides a macro for that function.

 

...

...

...

...

...

...

Noncompliant Code Example (assert)

In this noncompliant code example, a programmer attempts to access their own verification functionality by suppressing the assert macro and instead sending control to a user-defined assertthe standard assert() macro is suppressed in an attempt to pass it as a function pointer to the  execute_handler() function.Suppose the custom <myassert.h> declares a function  Attempting to suppress the assert() that does nonstandard verification, and the standard <assert.h> defines an assert macro as required by the standard macro is undefined behavior.

Code Block
bgColor#FFcccc
langc

#include <myassert.h>
#include <assert.h>
 
typedef void fullAssert(*handler_type)(int e) {
  assert(0 < e); // invoke standard library assert()
  (assert)(0 < e);   // assert() macro suppressed, calling function assert()
}

...

);
 
void execute_handler(handler_type handler, int value) {
  handler(value);
}
 
void func(int e) {
  execute_handler(&(assert), e < 0);
} 

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().In this compliant solution, the assert() macro is wrapped in a helper function, removing the undefined behavior:

Code Block
bgColor#ccccff
langc

#include <myassert<assert.h>
 
#include <assert.h>
typedef void (*handler_type)(int);
 
void fullAssert(execute_handler(handler_type handler, int evalue) {
  handler(value);
}
 
static void assert_handler(0int < evalue); // standard library {
  assert(value);
}
 
void func(int myassert(e); // well defined custom assertion function
}
{
  execute_handler(&assert_handler, e < 0);
}

Noncompliant Code Example (Redefining errno)

Legacy code is apt to include an incorrect declaration, such as the following .in this noncompliant code example:

Code Block
bgColor#FFcccc
langc

extern int errno;

Compliant Solution (

...

Declaring errno)

The This compliant solution demonstrates the correct way to declare errno is to include by including the header <errno.h>.:

Code Block
bgColor#ccccff
langc

#include <errno.h>

Implementations conforming to C99 are C-conforming implementations are required to declare errno in <errno.h>, although some historic implementations failed to do so.

Risk Assessment

Accessing objects or function functions underlying these macros does not produce defined behavior, which may lead to incorrect or unexpected program the specific macros enumerated in this rule is undefined behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MSC38-C

low

Low

unlikely

Unlikely

medium

Medium

P2

L3

Related Guidelines

ISO/IEC 9899:1999: all sections indicated by the undefined behavior items noted above

Bibliography

Automated Detection

ToolVersionCheckerDescription
Astrée
Include Page
Astrée_V
Astrée_V

Supported, but no explicit checker
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

BADMACRO.STDARG_H

Use of <stdarg.h> Feature

Cppcheck Premium

Include Page
Cppcheck Premium_V
Cppcheck Premium_V

premium-cert-msc38-cFully implemented
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C3437, C3475

C++3127, C++5039


Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V
CERT_C-MSC38-a
 A function-like macro shall not be invoked without all of its arguments

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule MSC38-CChecks for predefined macro used as an object (rule fully covered)
RuleChecker
Include Page
RuleChecker_V
RuleChecker_V

Supported, but no explicit checker

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

CERT CDCL37-C. Do not declare or define a reserved identifierPrior to 2018-01-12: CERT: Unspecified Relationship

Bibliography

ISO/IEC 9899:20247.1.4, "Use of Library Functions"


...

Image Added Image Added Image AddedImage Removed      49. Miscellaneous (MSC)      MSC39-C. Do not call va_arg() on a va_list that has indeterminate value