I hate the fact that GDK does not include debug build libraries. Many of the debugging features of VS2008 are disabled since we can not #define _DEBUG in our projects...
Mostly, I hate not being able to utilize the TRACE/VERIFY/ASSERT macros while debugging so that I can catch errors in the early stages...
I'm a firm believer in ASSERT()-ing errors in that they allow me to identify (during debugging) that perhaps my assumption is incorrect... With out the _DEBUG pre-processor directive (among other things - [LIBCMTD for instance]) I lose those valuable (to me anyways) debugging aides...
So, I've wrote my own MY* equivalent versions and here they are:
Debugging.h file:
//***************************************************************************************
//
// File Name: Debugging.h
// Purpose: Declares some special DEBUG macros and supporting functions
//
// Revisions: 4/2/2010 - JWH - Original version.
//
// Special Notes: The macros defined in this file *currently* require the related
// functions that are declared above them.
//
// None of the DarkGDK projects can work with debug versions
// of the CRT (LIBCMTD) since the static library (.LIB) files
// that are offered are all "Release" build versions. This causes
// problems when trying to debug your own applications.
//
// In an effort to alleviate some of the issues created by not
// allowing TRACE/VERIFY/ASSERT macros within code, we have
// written our own that *do* work with DarkGDK.
//
// Disclaimer: You may use in any way that you see fit... Enjoy!
//
//***************************************************************************************
// Copyright (c) 2010, Dark-Tools Development Team. All Rights Reserved.
//***************************************************************************************
#ifndef OTI_DEBUGGING_H__
#define OTI_DEBUGGING_H__
namespace TOOLBOX {
/* Function declarations */
void DebugLog(const char *strMsg, ...);
int AssertLog( const char *exp, const char *fname, unsigned int fline );
void ErrorBox(const char *strMsg, ...);
#if !defined( NDEBUG )
# define MYTRACE TOOLBOX::DebugLog
# define MYASSERT(exp) (void) ((exp) || (TOOLBOX::AssertLog(#exp, __FILE__, __LINE__)))
# define MYVERIFY(exp) (int) ((exp) || (TOOLBOX::AssertLog(#exp, __FILE__, __LINE__)))
# define MYERROR TOOLBOX::ErrorBox
#else
# define MYTRACE 1 ? (void) 0 : TOOLBOX::DebugLog
# define MYASSERT(exp) ((void) 0)
# define MYVERIFY(exp) (exp) ? TRUE : FALSE
# define MYERROR 1 ? (void) 0 : TOOLBOX::ErrorBox
#endif // DEBUG...
}; // namespace TOOLBOX
#endif //OTI_DEBUGGING_H__
and the supporting Debugging.CPP file:
//***************************************************************************************
//
// File Name: Debugging.cpp
// Purpose: Defines some DEBUG supporting functions.
//
// Revisions: 4/2/2010 - JWH - Original version.
//
// Special Notes: Only uses the ASCII version of some functions that expect
// char* strings.
//
// None of the DarkGDK projects can work with debug versions
// of the CRT (LIBCMTD) since the static library (.LIB) files
// that are offered are all "Release" build versions. This causes
// problems when trying to debug your own applications.
//
// In an effort to alleviate some of the issues created by not
// allowing TRACE/VERIFY/ASSERT macros within code, we have
// written our own that *do* work with DarkGDK.
//
// Disclaimer: You may use in any way that you see fit... Enjoy!
//
//***************************************************************************************
// Copyright (c) 2010, Dark-Tools Development Team. All Rights Reserved.
//***************************************************************************************
#include <windows.h>
#include <stdio.h>
namespace TOOLBOX {
#define _ASSERT_STRING_TEXT_ "%s\n%s%s\n%s%s\n%s%d\n%s%s\n\n"
#define _ASSERTION_FAILED_TEXT_ "Assertion Failed!"
#define _MODULE_INTRO_TEXT_ " Program: "
#define _FILE_INTRO_TEXT_ " File: "
#define _LINE_INTRO_TEXT_ " Line: "
#define _EXPRESSION_INTRO_TEXT_ " Expression: "
void DebugLog( const char *strMsg, ... ) {
if (NULL != strMsg) {
char strBuffer[1024];
va_list args;
memset(strBuffer, 0, 1024);
va_start(args, strMsg);
_vsnprintf_s( strBuffer, 1024, _TRUNCATE, strMsg, args );
va_end(args);
OutputDebugStringA(strBuffer);
}
}
int AssertLog( const char *exp, const char *fname, unsigned int fline ) {
if ((NULL != exp) && (NULL != fname)) {
char strBuffer[1024];
char module_name[MAX_PATH];
GetModuleFileNameA(NULL, module_name, MAX_PATH);
_snprintf_s( strBuffer, 1024, _TRUNCATE, _ASSERT_STRING_TEXT_, _ASSERTION_FAILED_TEXT_,
_MODULE_INTRO_TEXT_, module_name, _FILE_INTRO_TEXT_, fname, _LINE_INTRO_TEXT_,
fline, _EXPRESSION_INTRO_TEXT_, exp );
//**********************************************************
// TODO: 4/2/2010 - JWH - Add StackWalk Functionality
//**********************************************************
OutputDebugStringA(strBuffer); /* Send it to Output Window */
int flags = MB_TASKMODAL | MB_ICONERROR | MB_RETRYCANCEL | MB_DEFBUTTON2;
if ( IDCANCEL == MessageBoxA( NULL, strBuffer, "ASSERTION FAILURE!", flags ))
exit(1); /* If the assertion fails - We *should* exit the program */
}
return FALSE;
}
void ErrorBox( const char *strMsg, ... ) {
if (NULL != strMsg) {
char strBuffer[1024];
va_list args;
memset(strBuffer, 0, 1024);
va_start(args, strMsg);
_vsnprintf_s( strBuffer, 1024, _TRUNCATE, strMsg, args );
va_end(args);
int flags = MB_TASKMODAL | MB_ICONERROR | MB_RETRYCANCEL | MB_DEFBUTTON2;
if ( IDCANCEL == MessageBoxA( NULL, strBuffer, "ERROR BOX!", flags ))
exit(1); /* If the assertion fails - We *should* exit the program */
}
}
};
If you're at all familiar with ASSERT/TRACE/VERIFY, you have probably already made your own versions; however, this version includes a new definition: MYERROR() whereby an error message is displayed - without the need for a failed ASSERT. Simply call MYERROR(msg) and you get an error box stating the error message... Very handy stuff, indeed...
Enjoy,
JTK