我寫(xiě)程序有個(gè)習(xí)慣,就是給那些獨(dú)立于任何接口的常用宏放在一個(gè)全局頭文件c.h中,然后不論在每個(gè).c文件中都包含該頭文件,這樣可以方便調(diào)用,貌似是從
postgreSQL中學(xué)到的.c.h中還有調(diào)試宏,可以很快定位程序異常,并打印異常原因及調(diào)用層次,另外,還可以用宏開(kāi)關(guān)的形式定義調(diào)試級(jí)別,以控制
輸出何種調(diào)試信息,一共有4級(jí),最高級(jí)是給程序員看的,給出最詳盡的異常信息;下一級(jí)是用戶可以看的,不會(huì)輸出接口內(nèi)部的異常信息,實(shí)現(xiàn)接口內(nèi)部隱藏等
等。該頭文件在不斷完善中 ,先給出部分代碼如下 :
/* c.h */
#ifndef _C_H
#define _C_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#define Delay(n) do { int i,j,k; /
for(k=0;k<n;k++) for(i=0;i<8999;i++) for(j=0;j<8999;j++); }while(0)
#define MAKE_RAND(M,N) ((M)+rand()/(RAND_MAX/((N)-(M)+1)+1))
#define NELEMS(x) ((sizeof(x))/(sizeof((x)[0])))
//n是2的冪次,如4,8,16
#define Round_Up(x,n) (((x)+((n)-1))&(~((n)-1)))
#define offsetof(ptype, MEMBER) ((size_t) &((ptype)0)->MEMBER)
#define container_of(ptr,ptype, member) /
(ptype)((char *)ptr-offsetof(ptype,member))
#define show_software_edition() do{/
printf("/nLast Compiled on %s at %s/n/n",__DATE__,__TIME__);/
}while(0)
//注意以下宏在使用時(shí),如果__VA_ARGS__中消息過(guò)長(zhǎng)可以分行,但是
//注意分行時(shí)不要在中間插入逗號(hào),否則就會(huì)當(dāng)作參數(shù)了
//字符串分行時(shí)會(huì)自動(dòng)進(jìn)行合并,如
/*
return_val_if_fail(
pp != 0 && *pp != 0,
0,
"In %s %s Line %d , "
"Memory Find Failed",
file , func , line
);
若在"In %s %s Line %d , "后面加逗號(hào),"Memory Find Failed"將被當(dāng)作第一個(gè)參數(shù)
*/
/*
if(x>0)
return_if_fail(x>5);
else ...
可能會(huì)出錯(cuò),等價(jià)形式為
if(x>0)
if(!(x>5)){
};
else ...
因?yàn)閞eturn_if_fail尾部的分號(hào)截?cái)嗔松弦粋€(gè)if,所以else會(huì)提示找不到
上一個(gè)if。
解決辦法為將return_if_fail用大括號(hào)括起來(lái)
if(x>0) {
return_if_fail(x>5);
}
else
*/
#define myassert(exp) ((void)((exp)||(fprintf(stderr,/
"/n/nAssert !! In %s -> %s -> %d :: %s/n"/
,__FILE__,__FUNCTION__,__LINE__,#exp),abort(),0)))
#if defined(DEBUG0)
#define return_val_if_fail(p,ret,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
fprintf(stdout,"/nWarning !! In %s %s Line %d , "#p" Failed ./n", /
__FILE__,__FUNCTION__,__LINE__); /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"Error Message : %s",error_msg); /
return ret ; /
} /
} while(0)
#define return_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
fprintf(stdout,"/nWarning !! In %s %s Line %d , "#p" Failed ./n", /
__FILE__,__FUNCTION__,__LINE__); /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"Error Message : %s",error_msg); /
return ; /
} /
} while(0)
#define err_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
fprintf(stdout,"/nWarning !! In %s %s Line %d , "#p" Failed ./n", /
__FILE__,__FUNCTION__,__LINE__); /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"Error Message : %s",error_msg); /
} /
} while(0)
#ifndef DISABLE_SHOW
#define Show_Value(x,u) fprintf(stdout,"/nIn %s %s Line : %d , The Value of "#x" is %"#u" .",/
__FILE__,__FUNCTION__,__LINE__,x)
#else
#define Show_Value(x,u) ((void)(x))
#endif
#elif defined(DEBUG1)
#define return_val_if_fail(p,ret,...) do { /
int val = (p) ? 1:0 ; /
if(val==0) { /
char error_msg[128]; /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
return ret ; /
} /
} while(0)
#define return_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"/nError Message : %s",error_msg); /
return ; /
} /
} while(0)
#define err_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
char error_msg[128]; /
int size = sizeof error_msg/sizeof error_msg[0];/
snprintf(error_msg, size, " "__VA_ARGS__); /
error_msg[size-1]='/0'; /
if(*error_msg)fprintf(stdout,"/nError Message : %s",error_msg); /
} /
} while(0)
#ifndef DISABLE_SHOW
#define Show_Value(x,u) fprintf(stdout,"/nThe Value of "#x" is %"#u" .",x)
#else
#define Show_Value(x,u) ((void)(x))
#endif
#elif defined(DEBUG2)
#define return_val_if_fail(p,ret,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
return ret ; /
} /
} while(0)
#define return_if_fail(p,...) do { /
int val = (p) ? 1:0; /
if(val==0) { /
return ; /
} /
} while(0)
#define err_if_fail(p,...) do { /
int val = (p) ? 1:0; /
} while(0)
#ifndef DISABLE_SHOW
#define Show_Value(x,u) fprintf(stdout,"%"#u"",x)
#else
#define Show_Value(x,u) ((void)(x))
#endif
#elif defined(DISABLE_RETURN_DEBUG)
#define return_val_if_fail(p,ret,...) ((void)0)
#define return_if_fail(p,...) ((void)0)
#define err_if_fail(p,...) ((void)0)
#else
#define return_val_if_fail(p,ret,...) do { /
int val = (p) ? 1:0; /
} while(0)
#define return_if_fail(p,...) do { /
int val = (p) ? 1:0; /
} while(0)
#define err_if_fail(p,...) do { /
int val = (p) ? 1:0; /
} while(0)
#define Show_Value(x,u) ((void)(x))
#endif
#if defined(DEBUG0) || defined(DEBUG1) || defined(DEBUG2)
#ifndef DISABLE_D
#define D__ fprintf(stdout,"/nRunning Over %s %s Line %d .", /
__FILE__,__FUNCTION__,__LINE__);
#else
#define D__ ((void)0);
#endif
#ifndef DISABLE_MSG
#define err_msg(std,...) fprintf(std , __VA_ARGS__)
#else
#define err_msg(std,...) ((void)0)
#endif
#endif
#define Abs(a) ((a)>0 ? (a) : -(a))
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)>(b)?(b):(a))
#define Bzero(ptr,size) memset((ptr),0,(size))
#define Zero_Memory(ptr) Bzero(ptr,sizeof *(ptr))
#define Str_Macro(p) _Str_Macro(p)
#define _Str_Macro(p) #p
#define Strcmp(a,R,b) (strcmp(a,b) R 0)
#endif