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

Compare with Current View Page History

« Previous Version 29 Next »

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 below 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.185

185) This means that an implementation shall provide an actual function for each library function, even if it also provides a macro for that function.

asserterrnomath_errhandlingsetjmp
va_startva_argva_copyva_end

Noncompliant Code Example (assert)

In this example, the standard assert() macro is suppressed in an attempt to pass it as a function pointer to the  execute_handler() function. Attempting to suppress the assert() macro is undefined behavior.

#include <assert.h>
 
typedef void (*handler_type)(int);
 
void execute_handler(handler_type handler, int value) {
  handler(value);
}
 
void func(int e) {
  execute_handler(&(assert), e < 0);
} 

Compliant Solution (assert)

In this compliant solution, the assert() macro is wrapped in a helper function, removing the undefined behavior:

#include <assert.h>
 
typedef void (*handler_type)(int);
 
void execute_handler(handler_type handler, int value) {
  handler(value);
}
 
static void assert_handler(int value) {
  assert(value);
}
 
void func(int e) {
  execute_handler(&assert_handler, e < 0);
}

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 Vulnerabilities

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

Related Guidelines

Bibliography

ISO/IEC 9899:2011Subclause 7.1.4, "Use of Library Functions"

 

 

  • No labels