#define DEBUG是什么意思呢?
编译器在内存中会维护一张关于 #define的表结构。这里只是添加了一个表项叫DEBUG,没有内容。这种写法本身没有错误,倒是下面运用到了一个技巧:#ifndef是查询该表有没有该表项,如果没有即为成功,此时将会编译之后的程序语句。一般是为了调试而设置的一些程序。待发布release版本时,没有了DEBUG表项,所以很多语句就不编译了,此时的程序被极度优化,EXE文件也小了很多倍。
我的理解是这样的:
这个正如#DEFINE R 3.142
同样理解R就代表了3.142
在定义#DEFINE DEBUG时,后面的内容是空的,因为我的下面程序没有出现错误:此段代码定义了一个test什么都没定义,使用cout << test <<end;时报错,而在使用我们认为不可能正确的cout << test 1 << endl;时却正确。所以test就是什么都没有。
#define test
#include "iostream.h"
void main()
{
cout << test 1 << endl;
}
#define DEBUG,定义没有值的DEBUG主要是用于控制调试程序的运行。当定义了DEBUG时"#ifdef DEBUG" 则执行某些调试用的代码,若把"#define DEBUG"删除了后,"#ifdef DEBUG" 就可以使程序不执行某些代码。
把DEBUG替换成空字符串,只是表示有DEBUG这个东西,使#if defined DEBUG 可以编译
其它编译器不清楚,VC下会经常出现,在VC下DEBUG和NDEBUG是微软定义好的,
在debug版本编译下,编译器会默认定义了DEBUG这个宏;
在release(发布版)版本下,编译器会默认定义宏NDEBUG
所以最好不要自已把DEBUG和NDEBUG宏定义成其它的意思
这样就可以利用
#ifdefDEBUG
/****做debug下要做的事*****
#else
/**做release版本下的事*******/
#endif
这样做的好处是无论在debug下还是release下,可以用同一个代码
#
define DEBUG
main()
{
# ifdef DEBUG
printf( "Debugging\n");
# else
printf( "Not debugging\n");
# endif
printf( "Running\n");
}
main()
{
# ifdef DEBUG
printf( "Debugging\n");
# else
printf( "Not debugging\n");
# endif
printf( "Running\n");
}
在用vc时,利用AppWizard会产生如下代码:
DE>
DE>
#
ifdef _DEBUG
# define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
# endif
# define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
# endif
对于
#define new DEBUG_NEW
首先看msdn的解释:
Assists in finding memory leaks. You can use DEBUG_NEW everywhere in your program that you would ordinarily use the new operator to allocate heap storage.
In debug mode (when the _DEBUG symbol is defined), DEBUG_NEW keeps track of the filename and line number for each object that it allocates. Then, when you use the CMemoryState::DumpAllObjectsSincemember function, each object allocated with DEBUG_NEW is shown with the filename and line number where it was allocated.
To use DEBUG_NEW, insert the following directive into your source files:
#define new DEBUG_NEW
On
ce you insert this directive, the preprocessor will insert DEBUG_NEW wherever you use new, and MFC does the rest. When you compile a release version of your program, DEBUG_NEW resolves to a simple newoperation, and the filename and line number information is not generated.
再查看定义:
DE>
DE>
#
ifdef _DEBUG
void * AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
# define DEBUG_NEW new(THIS_FILE, __LINE__)
# else
# define DEBUG_NEW new
# endif
void * AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
# define DEBUG_NEW new(THIS_FILE, __LINE__)
# else
# define DEBUG_NEW new
# endif
这样就很清楚了,当在debug模式下时,我们分配内存时的new被替换成DEBUG_NEW,而这个DEBUG_NEW不仅要传入内存块的大小,还要传入源文件名和行号,这就有个好处,即当发生内存泄漏时,我们可以在调试模式下定位到该问题代码处。若删掉该句,就不能进行定位了。而在release版本下的new就是简单的new,并不会传入文件名和行号。
因此,我们在开发代码阶段,保留上述代码是值得的。
#
ifdef DEBUG
# define F_OUT printf( "%s:", __FUNCTION__);fflush(stdout);
# define L_OUT printf( "%s:%d:", __FILE__, __LINE__);fflush(stdout);
# define A_OUT printf( "%s:%d:%s:", __FILE__, __LINE__, __FUNCTION__);fflush(stdout);
# define D_OUT printf( "DEBUG:");fflush(stdout);
# define F_PRINTF(fmt, arg...) F_OUT printf(fmt, ##arg)
# define L_PRINTF(fmt, arg...) L_OUT printf(fmt, ##arg)
# define A_PRINTF(fmt, arg...) A_OUT printf(fmt, ##arg)
# define PRINTF(fmt, arg...) D_OUT printf(fmt, ##arg)
# define DBUG(a) {a;}
# else
# define F_OUT
# define L_OUT
# define A_OUT
# define D_OUT
# define F_PRINTF(fmt, arg...)
# define L_PRINTF(fmt, arg...)
# define A_PRINTF(fmt, arg...)
# define PRINTF(fmt, arg...)
# define DBUG(a)
# endif
# define F_PERROR(fmt) F_OUT perror(fmt)
# define L_PERROR(fmt) L_OUT perror(fmt)
# define A_PERROR(fmt) A_OUT perror(fmt)
# define PERROR(fmt) D_OUT perror(fmt)
# define F_OUT printf( "%s:", __FUNCTION__);fflush(stdout);
# define L_OUT printf( "%s:%d:", __FILE__, __LINE__);fflush(stdout);
# define A_OUT printf( "%s:%d:%s:", __FILE__, __LINE__, __FUNCTION__);fflush(stdout);
# define D_OUT printf( "DEBUG:");fflush(stdout);
# define F_PRINTF(fmt, arg...) F_OUT printf(fmt, ##arg)
# define L_PRINTF(fmt, arg...) L_OUT printf(fmt, ##arg)
# define A_PRINTF(fmt, arg...) A_OUT printf(fmt, ##arg)
# define PRINTF(fmt, arg...) D_OUT printf(fmt, ##arg)
# define DBUG(a) {a;}
# else
# define F_OUT
# define L_OUT
# define A_OUT
# define D_OUT
# define F_PRINTF(fmt, arg...)
# define L_PRINTF(fmt, arg...)
# define A_PRINTF(fmt, arg...)
# define PRINTF(fmt, arg...)
# define DBUG(a)
# endif
# define F_PERROR(fmt) F_OUT perror(fmt)
# define L_PERROR(fmt) L_OUT perror(fmt)
# define A_PERROR(fmt) A_OUT perror(fmt)
# define PERROR(fmt) D_OUT perror(fmt)
博主小结:
通过取消debug定义删除掉调试阶段相关的代码,这是开发者必备的技巧。要使用这个技巧,先明确release版本和debug版本的区别