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