4.1 Introduction  -< ANSI C Rationale  -> 4.3 Character Handling              Index 

4.2  Diagnostics  <assert.h>

4.2.1  Program diagnostics

4.2.1.1  The assert macro

Some implementations tolerate an arbitrary scalar expression as the argument to assert, but the Committee decided to require correct operation only for int expressions.  For the sake of implementors, no hard and fast format for the output of a failing assertion is required; but the Standard mandates enough machinery to replicate the form shown in the footnote. 

It can be difficult or impossible to make assert a true function, so it is restricted to macro form only. 

To minimize the number of different methods for program termination, assert is now defined in terms of the abort function. 

Note that defining the macro NDEBUG to disable assertions may change the behavior of a program with no failing assertion if any argument expression to assert has side-effects, because the expression is no longer evaluated. 

It is possible to turn assertions off and on in different functions within a translation unit by defining (or undefining)  NDEBUG and including <assert.h> again.  The implementation of this behavior in <assert.h> is simple: undefine any previous definition of assert before providing the new one.  Thus the header might look like

        #undef assert
        #ifdef NDEBUG
         #define assert(ignore)  ((void) 0)
        #else
         extern void __gripe(char *_Expr, char *_File, int _Line);
         #define assert(expr) \
           ( (expr)? (void)0 : __gripe(#expr, __FILE__, __LINE__) )
        #endif
Note that assert must expand to a void expression, so the more obvious if statement does not suffice as a definition of assert Note also the avoidance of names in a header which would conflict with the user's name space (see §3.1.2.1). 
4.1 Introduction  -< ANSI C Rationale  -> 4.3 Character Handling              Index