snprintf变量列表不会将枚举转换为char *

时间:2014-09-15 15:05:10

标签: c++ c printf variadic-functions

我一直在做一项改变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 *,...)'

摆脱这种情况的一个明显选择是为枚举打印提供整数类型转换。

由于这可能是一个单调乏味的过程,我很想知道我是否可以通过其他方式解决这个问题?

请分享您的观点。

提前致谢。

1 个答案:

答案 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的电话。因此,请删除宏中的##和调用站点中的额外数据。