在后台程序運行出問題時,詳盡的日志是抓錯不可缺少的幫手,這里提供一個能自動記錄日志觸發點文件名、行號、函數名的方法,關鍵是利用C99新增的預處理標識符__VA_ARGS__
先介紹幾個編譯器內置的宏定義,這些宏定義不僅可以幫助我們完成跨平台的源碼編寫,靈活使用也可以巧妙地幫我們輸出非常有用的調試信息。
ANSI C標准中有幾個標准預定義宏(也是常用的):
__LINE__:在源代碼中插入當前源代碼行號;
__FILE__:在源文件中插入當前源文件名;
__DATE__:在源文件中插入當前的編譯日期
__TIME__:在源文件中插入當前編譯時間;
__STDC__:當要求程序嚴格遵循ANSI C標准時該標識被賦值為1;
__cplusplus:當編寫C++程序時該標識符被定義。
代碼:
#define LOG(level, format, ...) / do { / fprintf(stderr, "[%s|%s@%s,%d] " format "/n", / level, __func__, __FILE__, __LINE__, ##__VA_ARGS__ ); / } while (0) int main() { LOG(LOG_DEBUG, "a=%d", 10); return 0; }
運行結果:
[DEBUG|main@a.c,17] a=10
限制是format不能是變量,必須是常量字符串,如果要記錄一個變量字符串,不能像printf那樣printf(s)了,要LOG("DEBUG", "%s", s)。
另外還有一種:
//============================================================================ // Name : debug.cpp // Author : boyce // Version : 1.0 // Copyright : pku // Description : Hello World in C++, Ansi-style //============================================================================ #include <stdio.h> #define __DEBUG__ #ifdef __DEBUG__ #define DEBUG(format,...) printf("File: "__FILE__", Line: %05d: "format"\n", __LINE__, ##__VA_ARGS__) #else #define DEBUG(format,...) #endif int main(int argc, char **argv) { char str[]="Hello World"; DEBUG("A ha, check me: %s",str); return 0; }