#include <stdio.h>
#define LOG_D(x) { printf("D:"); printf(x);}
#define LOG_E(x) { printf("E:"); printf(x);}
void test(void)
{
LOG_D("ALL is well " );
}
我有一个非常庞大的代码,它具有不同级别的日志,如上面的代码。 在最终测试的库中,我只需要一个错误日志,以减少代码大小。
所以我想要这样的东西
#define ENABLE_DEBUG_LOG 0
#define ENABLE_ERROR_LOG 1
#define LOG_D(x) {#if(ENABLE_DEBUG_LOG==1) printf("D:"); printf(x); #endif}
#define LOG_E(x) {#if(ENABLE_ERROR_LOG==1) printf("E:"); printf(x);#endif}
我添加了#if(ENABLE_DEBUG_LOG == 1)只是为了解释,我需要一些可以编译的解决方案。
答案 0 :(得分:5)
另一个选项 - 您只需评论/取消注释ENABLE_DEBUG_LOG
和ENABLE_ERROR_LOG
即可禁用/启用相应的日志级别。
// #define ENABLE_DEBUG_LOG // disable DEBUG_LOG
#define ENABLE_ERROR_LOG // enable ERROR_LOG
#ifdef ENABLE_DEBUG_LOG
#define LOG_D(x) { printf("D:"); printf(x);}
#else
#define LOG_D(x) // nothing
#endif
#ifdef ENABLE_ERROR_LOG
#define LOG_E(x) { printf("E:"); printf(x);}
#else
#define LOG_E(x) // nothing
#endif
答案 1 :(得分:4)
您无法嵌套预处理程序指令。但您可以制作两个版本的宏,并在#if
或#ifdef
的独占部分中定义它们:
#define ENABLE_DEBUG_LOG 0
#if ENABLE_DEBUG_LOG != 0
#define LOG_D(...) printf("D: " __VA_ARGS__)
#else
#define LOG_D(...) // Do nothing
#endif
在这里,禁用版只是&#34;吃&#34; LOG_D
宏,并没有做任何事情。 (请注意,未定义的宏在#if
条件中被视为值0。)
答案 2 :(得分:3)
你应该可以这样做:
#if ENABLE_DEBUG_LOG == 1
# define LOG_D(x) { printf("D:"); printf(x);}
#else
# define LOG_D(x)
#end
这样,如果ENABLE_DEBUG_LOG
未定义或具有不同的值,调试日志语句就会消失。
答案 3 :(得分:1)
我不确定这是否是您想要的,但您可以查看#ifdef
指令。
#include <stdio.h>
/* #define DEBUG */
#ifdef DEBUG
#define LOG_D(x) { printf("D: %s\n",x); }
#define LOG_E(x) { printf("E: %s\n",x); }
#else
#define LOG_D(x)
#define LOG_E(x)
#endif
int main() {
LOG_D("blah...");
return 0;
}
如果您取消注释#define DEBUG
行,该程序将打印D: blah...
答案 4 :(得分:1)
关于其他答案,在未启用宏时将宏定义为完全空是不明智的,因为在启用错误日志记录时会出错:
if (some_error)
LOG_E("Oops...");
do_something();
如果LOG_E(x)
扩展为空,那么只有在do_something()
为真时才会调用some_error
,这可能不是您想要的!
所以你可以像这样定义LOG_E(x)
的“无所事事”变体:
#define LOG_E(x) { }
我倾向于使用do { blah; } while (0)
构造,而不是以大括号开头和结尾,因为当你使用它时,它会强制你在结尾处加一个分号。像这样:
#if ENABLE_ERROR_LOG
#define LOG_E(x) do { printf("E:"); printf(x); } while (0)
#else
#define LOG_E(x) do ; while (0)
#endif
然后,
if (some_error)
LOG_E("Oops")
由于缺少分号,会导致语法错误,迫使您将其写为
if (some_error)
LOG_E("Oops");
您可以做的另一件事是将"E:"
或"D:"
标记与传入的字符串连接起来,尽管这需要参数为字符串文字,而不是通用char *
:
#define LOG_E(x) printf("E:" x)
您可以做的另一件事是使用可变数量的参数(可变参数宏)定义宏以增加选项:
#define LOG_E(...) printf("E:" __VA_ARGS__)
然后你可以这样做:
if (some_error)
LOG_E("Oops, got error: %d\n", some_error);
您可以做的另一件事是让编译器优化对printf
的调用并将其定义如下:
#define LOG_E(...) do if (ENABLE_ERROR_LOG) printf("E:" __VA_ARGS__); while (0)
一个体面的编译器会注意到if
条件是常量,并且要么完全调用printf
(如果常量条件为假),要么包含它(如果常量条件为真) )。对于某些编译器,您可能需要在if
语句中禁止有关常量条件的警告。