带有可变参数的C预处理器宏,记录器

时间:2019-05-08 09:50:02

标签: c preprocessor

我想为调试和程序流控制开发一套简单的记录器宏。 第一种方法是安静地正常工作,但是有些小问题困扰着我。

logger.h

#ifndef LOGGER_H
#define LOGGER_H

#include <stdio.h>
#include <stdint.h>

#ifdef DEBUG
#define DEFAULT_STREAM (stdout)
#define MESSAGE_IDENTIFIER_LENGTH ((uint8_t) 10)
#define FUNCTION_NAME_LENGTH ((uint8_t) 20)
#define FILE_PATH_LENGTH ((uint8_t) 40)

#define LOG_MESSAGE(STREAM, MESSAGE_IDENTIFIER, ...) \
    do { \
    fprintf(STREAM,"[ %*.*s ] [ %*.*s ] [ %*.*s:%04d ]: ", \
                    MESSAGE_IDENTIFIER_LENGTH, MESSAGE_IDENTIFIER_LENGTH, MESSAGE_IDENTIFIER, \
                    FUNCTION_NAME_LENGTH, FUNCTION_NAME_LENGTH, __FUNCTION__, \
                    FILE_PATH_LENGTH, FILE_PATH_LENGTH, __FILE__, __LINE__ \
                    ); \
    fprintf(STREAM, __VA_ARGS__ ); \
    fputs("\n", STREAM); \
    } while (0)

#define LOG_INFO(ARGS...) LOG_MESSAGE(DEFAULT_STREAM, "INFO", ARGS)
#define LOG_ERROR(ARGS...) LOG_MESSAGE(DEFAULT_STREAM, "ERROR", ARGS)
#define LOG_WARNING(ARGS...) LOG_MESSAGE(DEFAULT_STREAM, "WARNING", ARGS)

#else
#define LOG_MESSAGE(STREAM, MESSAGE_IDENTIFIER, ...) ((void) 0)
#define LOG_INFO(ARGS...) ((void) 0)
#define LOG_ERROR(ARGS...) ((void) 0)
#define LOG_WARNING(ARGS...) ((void) 0)

#endif

#endif // LOGGER_H

我在宏中使用了两次fprintf和一次fput。但是我宁愿只使用fprintf一次。因为如果三遍调用fprintf,我会产生开销。

我已经看到许多开发人员在do {} while()子句中包装了诸如printf之类的语句。即使只是一个陈述。有人可以告诉我原因吗?

对于其他任何改进建议,我也感到满意。

0 个答案:

没有答案