2012-08-31 107 views
2

有沒有辦法在我的LOGGING -macro(如下所示)編譯期內發生日誌級檢查?它應該是可能的,因爲它在編譯時已經知道是否條件(如果(pLogLevel < = LOG_LEVEL))是true或false。下面是如何的宏可以使用例如:使用C預處理器指令編譯時間檢查

LOGGING(LOG_DEBUG, "FALSE - Wrong Marker\n");

原本我以爲一個#define#if指令可以幫助我,但this文章給我看,這是不可能的。這是源代碼,我的問題:

#ifndef __LOGGING_H__ 
#define __LOGGING_H__ 1 

#include <time.h> 

#define LOG_EMERG 0 
#define LOG_ALERT 1 
#define LOG_CRIT  2 
#define LOG_ERROR 3 
#define LOG_WARN  4 
#define LOG_NOTICE 5 
#define LOG_INFO  6 
#define LOG_DEBUG 7 
#define LOG_NONE  8 

/* set the global logging level here */ 
#define LOG_LEVEL LOG_INFO 

void print_timestamp(void); 

#if LOG_LEVEL == LOG_DEBUG 
#define _LOG_PREAMBLE          \ 
     fprintf(stdout, "%s:%d ", __FILE__, __LINE__); 
#else 
#define _LOG_PREAMBLE          \ 
     print_timestamp(); 
#endif 

#if LOG_LEVEL == LOG_EMERG 
#define _LOG_LEVEL fprintf(stdout, "EMERG "); 
#elif LOG_LEVEL == LOG_ALERT 
#define _LOG_LEVEL fprintf(stdout, "ALERT "); 
#elif LOG_LEVEL == LOG_CRIT 
#define _LOG_LEVEL fprintf(stdout, "CRIT "); 
#elif LOG_LEVEL == LOG_ERROR 
#define _LOG_LEVEL fprintf(stdout, "ERROR "); 
#elif LOG_LEVEL == LOG_WARN 
#define _LOG_LEVEL fprintf(stdout, "WARN "); 
#elif LOG_LEVEL == LOG_NOTICE 
#define _LOG_LEVEL fprintf(stdout, "NOTICE "); 
#elif LOG_LEVEL == LOG_INFO 
#define _LOG_LEVEL fprintf(stdout, "INFO "); 
#elif LOG_LEVEL == LOG_INFO 
#define _LOG_LEVEL fprintf(stdout, "DEBUG "); 
#else 
#define _LOG_LEVEL 
#endif 

#define LOGGING(pLogLevel, ...)        \ 
    /* change this to compile time conditional if possible */ \ 
    if (pLogLevel <= LOG_LEVEL)        \ 
    {               \ 
     _LOG_PREAMBLE           \ 
     _LOG_LEVEL           \ 
     fprintf(stdout, ##__VA_ARGS__);      \ 
    } 

#endif /* __LOGGING_H__ */ 
+0

機會是很不錯的編譯器將消除您的日誌記錄代碼()宏時,當你打開的優化條件爲假,並且當條件爲真時,它將消除if()條件檢查 - 只在代碼中留下if()的主體。如果沒有,我會將它作爲編譯器的錯誤提交給編譯器。 – nos

+0

這是代碼生成器的工作。它可以看到if()語句始終爲false,並且知道消除代碼。您不需要幫助,只需確保優化器已啓用。 –

+0

謝謝你們兩位。這些是有用的評論。編譯器或優化器分別在總是爲真或爲假的條件中啓用/禁用代碼是非常有意義的。 – dubbaluga

回答

2

一種方法是將日誌級別合併爲日誌宏。

這將創建一組根據日誌級別打開或關閉的宏。

您將使用這些宏,它們將顯示或不顯示,具體取決於編譯時的日誌級別。所以他們會像下面一樣使用。

LOGGING_LEVEL_DEBUG("a Debug log."); 
//.... some code 
LOGGING_LEVEL_EMERG("a Emerge log."); 

因此,宏定義看起來像下面這樣:

#define LOG_EMERG 0 
    #define LOG_ALERT 1 
    #define LOG_CRIT  2 
    #define LOG_ERROR 3 
    #define LOG_WARN  4 
    #define LOG_NOTICE 5 
    #define LOG_INFO  6 
    #define LOG_DEBUG 7 
    #define LOG_NONE  8 

    /* set the global logging level here */ 
    #define LOG_LEVEL LOG_INFO 

    void print_timestamp(void); 

    #if LOG_LEVEL >= LOG_DEBUG 
    #define _LOG_PREAMBLE          \ 
      fprintf(stdout, "%s:%d ", __FILE__, __LINE__); 
    #else 
    #define _LOG_PREAMBLE          \ 
      print_timestamp(); 
    #endif 

    #if LOG_LEVEL >= LOG_EMERG 
     #define LOGGING_LEVEL_EMERG(...) \ 
      {               \ 
       _LOG_PREAMBLE           \ 
       fprintf(stdout, "EMERG ");           \ 
       fprintf(stdout, ##__VA_ARGS__);      \ 
      } 

     #else 
     #define LOGGING_LEVEL_EMERG(...) 
     #endif 

     #if LOG_LEVEL >= LOG_ALERT 
     #define LOGGING_LEVEL_ALERT(...) \ 
      {               \ 
       _LOG_PREAMBLE           \ 
       fprintf(stdout, "ALERT ");           \ 
       fprintf(stdout, ##__VA_ARGS__);      \ 
      } 

     #else 
     #define LOGGING_LEVEL_ALERT(...) 
     #endif 
0

您可以定義自己的宏條件:

#if LOG_LEVEL > 0 
# define LOG(...) printf(__VA_ARGS__) 
#else 
# define LOG(...) 
#endif 

#if LOG_LEVEL > 1 
// and so forth