我正在实现一种日志调度程序,即 int32_t logf(const char *fmt, ...);
,它输出到不同的日志记录目标,具体取决于编译时使用的选项。
以下是摘录。
int32_t logf(const char *fmt, ...)
{
va_list va;
i32 res;
va_start(va, fmt);
res = S_PASS;
#ifdef LOG_UART
res = Uart_vprintf(fmt, va);
if (res != S_PASS) goto exit;
#endif /* LOG_UART */
#ifdef LOG_SYS
res = System_vprintf(fmt, va);
if (res != S_PASS) goto exit;
#endif /* LOG_SYS */
exit:
va_end(va);
return res;
}
现在...如果没有给出任何选项,记录器将(实际上是打算)成为一个空记录器。但是,我还需要调用 va_start()
和 va_end()
吗?
换句话说(暂时忽略 -Wunused-label),这是正确的吗:
int32_t logf(const char *fmt, ...)
{
va_list va;
i32 res;
va_start(va, fmt);
res = S_PASS;
exit:
va_end(va);
return res;
}
...还是这个?
int32_t logf(const char *fmt, ...)
{
i32 res;
res = S_PASS;
return res;
}
更新
生成的空 函数实现不能被类似#define logf(fmt, ...) S_PASS;
的函数式宏替换。
现有代码库定义了 typedef int32_t(*logFunc)(const char *fmt, ...);
因此指向 logf 的指针必须是可存储的。
最佳答案
如果没有启用日志记录,我建议您改用一个空函数,或者可能是一个扩展为S_PASS
的可变参数宏。
也许是这样的
#if defined(LOG_UART) || defined(LOG_SYS)
inline int32_t logf(const char *fmt, ...)
{
// Your original code here...
}
#else
# define logf(x, ...) S_PASS
#endif
以上是如果您在 header 中定义函数。如果您的 header 中只有一个声明与源文件中的定义几乎相同。
头文件:
#if defined(LOG_UART) || defined(LOG_SYS)
int32_t logf(const char *fmt, ...);
#else
# define logf(x, ...) S_PASS
#endif
源文件:
#if defined(LOG_UART) || defined(LOG_SYS)
inline int32_t logf(const char *fmt, ...)
{
// Your original code here...
}
#endif
在您对函数指针发表评论之后,最好的解决方案可能是拥有一个内联函数函数,仅 返回
S_PASS`:
#if defined(LOG_UART) || defined(LOG_SYS)
int32_t logf(const char *fmt, ...);
#else
inline int32_t logf(const char *fmt, ...) { return S_PASS; }
#endif
关于c - 可变记录器调度程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40628685/