【问题标题】:function polymorphisms depending on debug level取决于调试级别的函数多态性
【发布时间】:2019-06-22 08:16:33
【问题描述】:

我想更改以下代码:

#ifdef CONSOLE_VERBOSE_DEBUG
    printf("this debug error message is printed to the console");
#elseif FILE_VERBOSE_DEBUG
    FILE *log = fopen(...);
    ...
    fprintf();
    fclose();
#else 
    ((void) 0) // no debugging

变成类似的东西

callThePropperDebugFct("message");

并根据定义的 DEBUG 级别将这一调用指向正确包含的头文件中声明的函数

我知道这与 c 多态性和函数指针有关,但我不知道该怎么做

【问题讨论】:

  • 定义一个日志函数,采用所需的参数(可能是 printf 样式的可变参数),并在该函数中包含条件编译部分?不要试图使事情过于复杂。 :)
  • 另请注意,#else 部分并不是真正需要的。
  • @Someprogrammerdude: ...但是如果在身边需要被最终的#endif“关闭”。

标签: c debugging logging polymorphism


【解决方案1】:
  1. 定义函数以在某些log.c 文件中记录您的消息
  2. 定义您的 callThePropperDebugFct 宏以调用正确的函数

log.c

void log_to_console(const char message)
{
    printf("%s", message);   
}

void log_to_file(const char *name, const char *message)
{
    FILE *f = fopen(name, "a");
    if (!f) return;

    fprintf(f, message);    

    fclose(f);
}

log.h

void log_to_console(const char message);
void log_to_file(const char *name, const char *message);

#ifdef CONSOLE_VERBOSE_DEBUG
#define callThePropperDebugFct(message) log_to_console(message); 
#elseif FILE_VERBOSE_DEBUG
#define callThePropperDebugFct(message) log_to_file(LOG_FILE, message)
#else
#define callThePropperDebugFct(message)
#endif

但是您可以使用一些可变参数宏和可变数量的参数函数更进一步:

log.c

#include <stdarg.h>
#include <stdio.h>

void log_to_console(const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    //vsnprintf(buffer, sizeof buffe, fmt, args);
    vprintf(fmt, args);
    va_end(args);
}

void log_to_file(const char *name, const char *fmt, ...)
{
    FILE *f = fopen(name, "a");
    if (!f) return;

    va_list args;
    va_start(args, fmt);
    vfprintf(f, fmt, args);
    va_end(args);

    fclose(f);
}

log.h

void log_to_console(const char *fmt, ...);
void log_to_file(const char *name, const char *fmt, ...);

#ifdef CONSOLE_VERBOSE_DEBUG
#define callThePropperDebugFct(...) log_to_console("s", __VA_ARGS__)
#elseif FILE_VERBOSE_DEBUG
#define callThePropperDebugFct(...) log_to_file(LOG_FILE, "%s", __VA_ARGS__)
#else
#define callThePropperDebugFct(...)
#endif

【讨论】:

  • 我喜欢这种可变参数宏参数的使用,因为它在调试关闭时完全消除了调试函数的调用(包括可能复杂的评估/计算参数以放入调试消息中)。不错!
  • 为什么是do..while?扩展已经扩展为单个函数调用/语句。
【解决方案2】:
#if DEBUG_LEVEL 
#ifndef LOG_OUTPUT
#define LOG_OUTPUT stdio 
#endif
log_function(DEBUG_LEVEL, LOG_OUTPUT, const char *fmt, ...);
#endif

#ifdef __GNUC__
#define ATTR __attribute__((format (printf, 3, 4)));
#else
/* ..  */
#endif

void ATTR log_function(int DEBUG_LEVEL, FILE *LOG_OUTPUT, const char *fmt, ...)
{
    va_list args;
    /* some code */

    vfprintf(LOG_OUTPUT, fmt, args);    
}

【讨论】:

    猜你喜欢
    • 2017-04-24
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    相关资源
    最近更新 更多