SHOW() for debugging:
#define SHOW(X) cout << # X " = " << (X) << endl
The double-evaluation to expand the arguments trick: (E.g. Use the actual line number and not "__LINE__".)
/* Use CONCATENATE_AGAIN to expand the arguments to CONCATENATE */ #define CONCATENATE( x,y) CONCATENATE_AGAIN(x,y) #define CONCATENATE_AGAIN(x,y) x ## y
Static compile-time assertions.
E.g.:
#define CONCATENATE_4( a,b,c,d) CONCATENATE_4_AGAIN(a,b,c,d) #define CONCATENATE_4_AGAIN(a,b,c,d) a ## b ## c ## d /* Creates a typedef that's legal/illegal depending on EXPRESSION. * * Note that IDENTIFIER_TEXT is limited to "[a-zA-Z0-9_]*". * * (This may be replaced by static_assert() in future revisions of C++.) */ #define STATIC_ASSERT( EXPRESSION, IDENTIFIER_TEXT) \ typedef char CONCATENATE_4( static_assert____, IDENTIFIER_TEXT, \ ____failed_at_line____, __LINE__ ) \ [ (EXPRESSION) ? 1 : -1 ]
Used via:
typedef int32_t int4; STATIC_ASSERT( sizeof(int4) == 4, sizeof_int4_equal_4 );
Initializing an instance of class CodeLocation: (Storing File/Line/Function from the point of invocation -- this can *ONLY* be done with a macro or by directly accessing the __FILE__/__LINE__/etc macros at the source point.)
/* Note: Windows may have __FUNCTION__. C99 defines __func__. */ #define CURRENT_CODE_LOCATION() \ CodeLocation( __PRETTY_FUNCTION__, __FILE__, __LINE__ )
Subsequently used by MESSAGE/WARN/FAIL macros as a convenient source-location printing mechanism. For example:
#define WARN_IF_NAN(X) \ do \ { \ if ( isnan(X) != 0 ) \ WARN( # X " is NaN (Floating Point NOT-A-NUMBER)" ); \ if ( isinf(X) != 0 ) \ WARN( # X " is INF (Floating Point INFINITY)" ); \ } while ( false )
Assert/Unless macros. You can pass any token, including operators like '==', through a macro. So constructs like:
ASSERT( foo, ==, bar )
Or
UNLESS( foo, >=, 0, value=0; return false; );
Are legal. Assert/Unless macros can automatically add all sorts the nice useful info like CodeLocation, stack traces, or throwing exceptions / coredumping / exiting gracefully.
Making errno simplier:
#define ERRNO_FORMAT "errno= %d (\"%s\")" #define ERRNO_ARGS errno, strerror(errno) #define ERRNO_STREAM "errno= " << errno << " (\"" << strerror(errno) << "\") "
E.g. printf( "Open failed. " ERRNO_FORMAT, ERRNO_ARGS );