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

Compare with Current View Page History

« Previous Version 35 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 (Declaring 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 results in undefined 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