EA Assert


A simple lightweight package. Use...
                #include "EAAssert/eaassert.h"
            
And get the following macros... For compatibility reasons (with existing EATrace practice), there are synonyms for EA_ASSERT_MSG, defined as EA_ASSERT_MESSAGE and EA_ASSERT_M.

Enabling and Disabling

Whether or not EA_ASSERT is enabled hinges on the following logic...
        #ifdef EA_DEBUG
            #define EA_ASSERT_ENABLED
        #endif

        #ifndef EA_ASSERT
	        #if EA_ASSERT_ENABLED
		        #define EA_ASSERT(expr) ...definition of EA_ASSERT...
    	    #else
    		    #define EA_ASSERT(expr) ((void)0)
    	    #endif
        #endif
                

Design Considerations

Below are some thoughts that went into the creation of this package...

Integration

To use EA_ASSERT in your own code you just include the header and use it.

To overwrite the default handler for assert failure, you need to implement the following function

        bool EAAssertFailure(
        
            const char* expr,       // Stringized version of the assert expression.
            const char* filename,   // Name of the file in which the assert occured.
            int line,               // Line number on which the assert occured.
            const char* function,   // Name of the function the assert occured in.
            const char* msg,        // Optional descriptive message.
            va_list args            // Variable argument list (printf style) in case msg contains formatters.
            
        );	
    
The return value of this function should be true if you want the failed assert to break into the debugger and false if you want to continue running past the assert.

To enable the use of this function, use:

        EA::Assert::SetFailureCallback(&yourCallback);
        

The simplest possible implementation of this function (which happens to be the default) just returns true immediately, always triggering a debug break.

For reference, here's an example implementation of EAAssertFailure that you can copy paste into your own code.

        bool EAAssertFailure(const char* expr, const char* filename, int line, const char* function, const char* msg, va_list args)
        {
            const int size = 1024;
            char output[size + 1] = {};
            char fmtMsg[size + 1] = {};
            
            _vsnprintf(fmtMsg, size, msg, args);
            _snprintf(output, size, "%s(%d) : assert failed: '%s' in function: %s\n, message: %s", filename, line, expr, function, fmtMsg);    
            
            printf(output);
            
            return true;
        }
	

If You already Have Your Own Asserts

If you already have your own asserts and would like other technology to use yours, you can easily forward EA_ASSERT to your own implementation. The trick is in the #EA_ASSERT_HAVE_OWN_HEADER macro. Define this to the name of your own header file that has equivalents of the macros defined above (make sure you provide all of them). For example, you could put the following in a file called "game/my_own_awesome_assert.h"...
        #define EA_ASSERT(expr) MY_OWN_AWESOME_ASSERT(expr)
        #define EA_ASSERT_MSG(expr, msg) MY_OWN_AWESOME_ASSERT(expr)
        #define EA_ASSERT_FORMATTED(expr, fmt) MY_OWN_AWESOME_ASSERT(expr)
        #define EA_FAIL() MY_OWN_AWESOME_ASSERT(false)
        #define EA_FAIL_MSG(msg) MY_OWN_AWESOME_ASSERT(false)
        #define EA_FAIL_FORMATTED(fmt) MY_OWN_AWESOME_ASSERT(false)
	
Next, define #EA_ASSERT_HAVE_OWN_HEADER to "game/my_own_awesome_assert.h" (including the quotes) when you build EA_ASSERT using technology and it will automatically use your assert instead.

Frequently Asked Questions


Acknowledgements

Input for this package came from Paul Pedriana, Ian Davids, James Fairweather, Max Burke, Bob Summerwill and others.