I love my asserts. I use them like crazy throughout my code and catch errors faster than you and your whole testing department. :> The computer does exactly what I ASK of it, which sometimes is not the same as what I EXPECT of it. So I wrap up my expectations with assert macros so my computer friend and I stay on the same page. Happy happy joy joy.

In Qt, we have the Q_ASSERT macro. Qt default behavior is to abort on any Q_ASSERT macro failure. This is weird to me (even if it is common). Almost universally, I want to SEE what’s going on when I hit an assert. Sometimes the assertion turns out to be wrong and may need adjusting. Even if it’s right, sometimes it’s helpful to check the effect of the failed assertion. And certainly, being able to walk back up the stack trace is critical to determine where things went wrong. I can kill the program easily if I WANT to, but I may want to continue – it should be my choice. It’s a no-brainer!

So I don’t use Q_ASSERT. Here’s my cross-platform C++ assert macro hackery. It’s not perfect but it’s getting me by so far…

//-------------------------------------------------------------------//
//	AssertHelpers
//
//	This module attempts to provide ASSERT(), VERIFY(), and TRACE()
// functionality under a wide range of builds and platforms.
//
// ASSERT( test ) will break and notify if (test != true) in debug builds.
// It will evaporate away under release builds.

// VERIFY( test ) will always execute  but will only break
// and notify the user if (test != true) under debug builds.
//
//	TRACE( szFormat, ... ) will output to whatever std error output is
//	available.
// 
//	Copyright © 2011 A better Software.
//-------------------------------------------------------------------//

#ifndef ASSERT_HELPERS_H
#define ASSERT_HELPERS_H

#include "PragmaMessages.h"			// For convenience, often used together.

#ifndef ASSERT

	#ifdef _WIN32

		#ifdef false	// what was wrong with ASSERT() on windows?  Q_WS_WIN

            #define ASSERT(test) 
			#define TRACE(test)

		#else

			// Use _ASSERT()
			#ifndef _INC_CRTDBG
				#include 
			#endif // _INC_CRTDBG

			#define ASSERT(test) _ASSERT(test)
		#endif

    #else

		// QT for X11, Mac OS X, Embedded Linux
        #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
		
            // Sadly, Q_ASSERT kills off the app!  doh.
            // #define ASSERT(test) Q_ASSERT(test)
            // #define ASSERT(test) if (!(test)) {DebugBreak();}
            # define ASSERT(x) ((x) ? (void)0 : qWarning("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__))
            #define TRACE(test)

		#endif

	#endif

#endif // ASSERT

#ifndef VERIFY

	#ifdef _WIN32

		#ifdef _DEBUG
			#define VERIFY(test) ASSERT(test)
		#else
		
			// This pragma prevents warnings about "(test) == true;" type statements under release mode.
			#pragma warning(disable : 4553 )
		
			#define VERIFY(test) test

		#endif // _DEBUG

	#endif // _WIN32

#endif // VERIFY

#ifndef TRACE

	#ifdef _WIN32

           #ifndef _INC_CRTDBG
		#include 
	   #endif // _INC_CRTDBG

   	   #ifdef _DEBUG
		   #define TRACE(test) 	_CrtDbgReport( _CRT_WARN, NULL, NULL, NULL, test )
	   #else
		   #define TRACE(test)
	   #endif

        #endif // _WIN32

#endif // TRACE

#endif	// ASSERT_HELPERS_H

Leave a Reply