Using ASSERT(), VERIFY(), and TRACE() in non-MFC Applications
by Gabriel Fleseriu

When it comes to game development under C++, few people choose to use MFC. Still, I find the ASSERT(), VERIFY() and TRACE() macros useful. So I thought to write my own versions that work for any kind of project for Windows platforms.

A few reminders:

  • ASSERT() is supposed to evaluate its parameter, and if this is zero, to break the execution. In release mode, assert should expand to nothing.
  • VERIFY() is very similar to ASSERT(), except that in Release mode, it is supposed to expand to its parameter.
  • ASSERT() should be used with expressions that do not include any function call. For expressions that include a function call, you should use VERIFY(), so the function call is preserved in release mode.
  • TRACE() is the counterpart of printf(), except that it prints to the debug window. In Release mode, TRACE() also should expand to nothing.
  • None of the three macros imply any runtime penalty in release mode. The macros distinguish between debug and release mode by the pre-defined _DEBUG macro. This is specific to Microsoft Visual C++. If you are using some other compiler you might have to use some appropriate macro.
  • Since it makes no sense to re-invent the wheel, I peeked into the MFC code and build my macros similarly. For ASSERT() and VERIFY() I left the fancy "Debug assertion failed..." dialog boxes aside, and simply implemented a plain vanilla breakpoint.

    There are two files needed to support ASSERT(), VERIFY and TRACE(): debug.h and debug.cpp. You should include debug.h in some main header of your project. It does not pollute recurrent inclusions, since it does not include any file itself. You also should add debug.cpp to the source files of your project.

    Here they are:

    // file debug.h
    #ifndef __DEBUG_H__
    #define __DEBUG_H__
    #ifdef _DEBUG
    void _trace(char *fmt, ...);
    #define ASSERT(x) {if(!(x)) _asm{int 0x03}}
    #define VERIFY(x) {if(!(x)) _asm{int 0x03}}
    #else
    #define ASSERT(x)
    #define VERIFY(x) x
    #endif
    #ifdef _DEBUG
    #define TRACE _trace
    #else
    inline void _trace(LPCTSTR fmt, ...) { }
    #define TRACE  1 ? (void)0 : _trace
    #endif
    #endif // __DEBUG_H__
    
    
    //file debug.cpp
    #ifdef _DEBUG
    #include <stdio.h>
    #include <stdarg.h>
    #include <windows.h>
    void _trace(char *fmt, ...)
    {
    char out[1024];
    	va_list body;
    	va_start(body, fmt);
    	vsprintf(out, fmt, body);
    	va_end(body);
    	OutputDebugString(out);
    }
    #endif
    

    Discuss this article in the forums


    Date this article was posted to GameDev.net: 7/23/2002
    (Note that this date does not necessarily correspond to the date the article was written)

    See Also:
    Sweet Snippets

    © 1999-2011 Gamedev.net. All rights reserved. Terms of Use Privacy Policy
    Comments? Questions? Feedback? Click here!