Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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.

Noncompliant Code Example (assert)

In this example, the standard standard assert() macro is suppressed in favor of calling a user-defined assertan attempt to pass it as a function pointer to the  execute_handler() 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: Attempting to suppress the assert() macro is undefined behavior.

Code Block
bgColor#FFcccc
langc
#include <assert.h>
 
#include "myassert.h"typedef void (*handler_type)(int);
 
void fullAssert(execute_handler(handler_type handler, int evalue) {
   assert(e > 0); /* Invoke standard library assert() */
  (assert)(e > 0); /*
                    * assert() macro suppressed; calling
                    * function assert().
                    */
}

...

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 <assert.h>
 
#include "myassert.h"typedef void (*handler_type)(int);
 
void fullAssert(execute_handler(handler_type handler, int evalue) {
  handler(value);
}
 
static void assert(e > 0); /* Standard library assert() */
  myassert(e > 0); /* Well-defined custom assertion function */
}
_handler(int value) {
  assert(value);
}
 
void func(int e) {
  execute_handler(&assert_handler, e < 0);
}

Noncompliant Code Example (Redefining errno)

...

Bibliography

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