我一直在做一项改变CPP代码库中当前日志记录机制的任务。
当前版本就像printf,我们可以在其中编写
MYLOGGING(("Example Log :%s, Example Num: %d", String, Number));
现在,作为将其修改为新的日志记录机制的一部分,我想使用snprintf()将此完整输出转换为字符串。为此,我使用了变量列表。
代码就像
#define MYLOGGING(log_string,...) do { \
char buff[1024]; \
memset(buff, 0, sizeof(buff)); \
snprintf(buff, sizeof(buff), log_string, ##__VA_ARGS__); \
MYNEW_LOG(NewlogParams, buff); \
} while(0)
现在,我正面临一个问题。 现有的日志记录有许多实例,其中使用简单的%d打印一些枚举值。 在这种情况下,使用这个新代码,它会抛出以下错误。
错误:无法将参数'3'的'enumType'转换为'const char *' 'int snprintf(char *,size_t,const char *,...)'
摆脱这种情况的一个明显选择是为枚举打印提供整数类型转换。
由于这可能是一个单调乏味的过程,我很想知道我是否可以通过其他方式解决这个问题?
请分享您的观点。
提前致谢。
答案 0 :(得分:2)
通过将##
运算符附加到__VA_ARGS__
,您将格式参数转换为const char *
:
snprintf(buff, sizeof(buff), log_string, ##__VA_ARGS__);
将其更改为:
snprintf(buff, sizeof(buff), log_string, __VA_ARGS__);
并且转换应该有效。
实际上,在仔细查看你的问题后,我注意到了另一个问题。 ##
运算符确实不常见且可能不正确,但是,问题的主要原因似乎是调用MYLOGGING
MYLOGGING(("Example Log :%s, Example Num: %d", String, Number));
如果您使用-E
标志在GCC中编译对该宏的调用以输出预处理的源,您将从宏中扩展此行:
do { char buff[1024]; memset(buff, 0, sizeof(buff)); snprintf(buff, sizeof(buff), ("Example Log :%s, Example Num: %d", String, Number)); ....
您可以看到()
仍在那里,搞砸了snprintf
的电话。因此,请删除宏中的##
和调用站点中的额外数据。