在 C 中打印不同调试消息的正确方法?

Proper way to print different debug messages in C?

在使用和不使用 DEBUG 标志进行编译时,我需要针对相同的错误打印 msg1 和 msg2。例如

      fprintf( stderr,
#ifdef DEBUG
                      "error msg1 %s",__FILE__
#else
                      "error msg2"
#endif
              );

或其他方式可能是将这些 msg1msg2 传递给函数并使用 vfprintf() 打印它。 第二种方法可能会有 运行 时间开销。所以,我只是想知道这样做的更好方法是什么?

例如一个用例可能是需要使用 infodebug 标志编译代码。 info 可能是与用户相关的消息,debug 用于调试目的。 有什么建议么?

无条件调用 vfprintf 确实会带来一些额外的开销,用于打包额外参数 a,以便与可变参数列表函数一起使用。而且,条件编译可以让编译器注意到在DEBUG模式下调用fprintf除了格式字符串之外没有传递参数,而将其替换为fputs("error msg1", stderr)*

但是,这种开销很小,您不太可能注意到它,因为写入是无条件发生的,并且它将支配调用的时间。

* DEBUG 输出提供比非调试输出少 的细节的情况并不常见;通常,它是相反的。

您的调试标志是预处理器宏,因此将在编译时选择错误消息,这是您想要的行为吗?

我建议采用稍微不同的方法:

#define PRINT_INFO(msg1,msg2) if(dbg){fprintf(stderr,msg1);}\
                              else{fprintf(stderr,msg2);}

其中 dbg 标志可以在 运行 时间打开和关闭

您可以使用 variadic macros 进行更多尝试:

#define PRINT_INFO_VAR(msg1,msg2...) if(dbg){fprintf(stderr,msg1);}\
                                     else{fprintf(stderr,msg2);}

对于您给出的示例,它看起来像这样:

PRINT_INFO_VAR(msg1,msg2,a)

通常在代码中使用跟踪来帮助调试它,因此例如在您的 NULL 指针测试中,您可以添加诸如 if (ptr==NULL) DEBUG("Entering Null pointer"); 之类的东西。我只是告诉你,因为我不明白你为什么要同时使用 msg1msg2

我通常使用宏 DEBUG 和全局变量 verbose :

#define DEBUG(...)\
if(verbose && SHOW_ERROR) {\
printf("Error : %s, %d",__FUNCTION__, __LINE__);\
printf(__VA_ARGS__);\
}\
else if (verbose && SHOW_WARNING) {\
printf("Warning : %s, %d",__FUNCTION__, __LINE__);\
printf(__VA_ARGS__);\
}

示例:

#include <stdio.h>

#define SHOW_ERROR 1
#define SHOW_WARNING 2

int verbose = 1; 
int main()
{
  DEBUG("THIS WILL SHOW ERROR MSG");
  verbose = 2;
  DEBUG("THIS WILL SHOW WARNING MSG");
}

希望能帮到你。