linux 中C語言便於調試的宏定義編寫及 __FILE__,__FUNCTION__, __LINE__參數使用


在linux編程中,當文件數量變的衆多之後,使用gdb調試就是一場災難。因此在程序中加入合理的打印信息,定位錯誤出現的文件名,函數名,行號等信息,能更高效的定位到問題的所在。

     下面定義了宏,分別是WARNING,INFO,ERROR,SHOW_TIME,DEBUG等。利用了 __FILE__,_FUNCTION__, __LINE__等變量。。。

      _FILE____FUNCTION__ __LINE__ 從名字可以直接看出來了,對應的:代碼文件函數 行號


     下面就是定義的宏:

  1. #define ERROR(...) /    
  2. do{ /    
  3.     fprintf(stderr, "[ERROR  ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /    
  4.     fprintf(stderr, __VA_ARGS__); /    
  5. }while(0)    
  6.     
  7. #define WARNING(...) /    
  8. do{ /    
  9.     fprintf(stdout, "[WARNING]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /    
  10.     fprintf(stdout, __VA_ARGS__); /    
  11. }while(0)    
  12.     
  13. #define INFO(...) /    
  14. do{ /    
  15.     fprintf(stdout, "[INFO  ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /    
  16.     fprintf(stdout, __VA_ARGS__); /    
  17. }while(0)    
  18.     
  19.     
  20. #define SHOW_TIME(...) /    
  21. do{/    
  22.     extern unsigned long long gLatestTime;/    
  23.     timeval tp;/    
  24.     gettimeofday(&tp, NULL);/    
  25.     unsigned long long now = tp.tv_sec*1000000+tp.tv_usec; /    
  26.     if(gLatestTime != 0) /    
  27.     { /    
  28.         fprintf(stdout, ">>>>>>>>>Used Time: %s[%d], %s: %ld.%ld, %llu ms ", __FILE__, __LINE__, __func__, tp.tv_sec, tp.tv_usec, (now-gLatestTime)/1000);/    
  29.         fprintf(stdout, __VA_ARGS__); /    
  30.         fprintf(stdout, "/n"); /    
  31.     } /    
  32.     gLatestTime = now;/    
  33. }while(0)    
  34.     
  35.     
  36. #ifdef DEBUG    
  37. #define DBG(...) /    
  38. do{ /    
  39.     fprintf(stdout, "[DEBUG  ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /    
  40.     fprintf(stdout, __VA_ARGS__); /    
  41. }while(0)    
  42. #else    
  43. #define DBG(...)    
  44. #endif   
#define ERROR(...) /  
do{ /  
    fprintf(stderr, "[ERROR  ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /  
    fprintf(stderr, __VA_ARGS__); /  
}while(0)  
  
#define WARNING(...) /  
do{ /  
    fprintf(stdout, "[WARNING]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /  
    fprintf(stdout, __VA_ARGS__); /  
}while(0)  
  
#define INFO(...) /  
do{ /  
    fprintf(stdout, "[INFO  ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /  
    fprintf(stdout, __VA_ARGS__); /  
}while(0)  
  
  
#define SHOW_TIME(...) /  
do{/  
    extern unsigned long long gLatestTime;/  
    timeval tp;/  
    gettimeofday(&tp, NULL);/  
    unsigned long long now = tp.tv_sec*1000000+tp.tv_usec; /  
    if(gLatestTime != 0) /  
    { /  
        fprintf(stdout, ">>>>>>>>>Used Time: %s[%d], %s: %ld.%ld, %llu ms ", __FILE__, __LINE__, __func__, tp.tv_sec, tp.tv_usec, (now-gLatestTime)/1000);/  
        fprintf(stdout, __VA_ARGS__); /  
        fprintf(stdout, "/n"); /  
    } /  
    gLatestTime = now;/  
}while(0)  
  
  
#ifdef DEBUG  
#define DBG(...) /  
do{ /  
    fprintf(stdout, "[DEBUG  ]%s %s(Line %d): ",__FILE__,__FUNCTION__,__LINE__); /  
    fprintf(stdout, __VA_ARGS__); /  
}while(0)  
#else  
#define DBG(...)  
#endif 


         以上是定義的輸出文件信息,如果想輸出自定義的字符串(類似printf()的功能),可以使用可變參的形式傳遞。

        如上面的的最後一個DEBUG的定義:

        fprintf(stdout , __VA_ARGS__); 

        這行代碼使得用戶可以將自己的信息放在可變參裏面,例如:DBG("  I am from  %s " , "ICT"); 這句話的輸出分成兩部分前半部分打印文件名、函數名、行號,後半部分會輸出: I am from ICT  這句話。可變參給用戶提供了很好的自定義空間。 

       <將在下一篇博文中介紹一下" 可變參 "的用法>

 
   說明:
        stdout -- 標準輸出設備 (printf("..")) 同 stdout。 
        stderr -- 標準錯誤輸出設備 兩者默認向屏幕輸出。 

        但如果用轉向標準輸出到磁盤文件,則可看出兩者區別。stdout輸出到磁盤文件,stderr在屏幕。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章