1

我在扩展 ACE 日志记录宏时遇到了困难。这是一个基本问题,但我无法解决它。

我正在尝试用变量参数列表来制定我自己的 ACE 日志记录宏。我的编译器(gcc 版本 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC))支持该__VA_ARGS__标准。我目前的定义如下:

#define ERROR_PREFIX            ACE_TEXT("ERROR (%T)%?%I")
#define ERROR(FMT,...) ACE_DEBUG((LM_ERROR, ACE_TEXT(FMT) __VA_ARGS__))

我想通过这个调用序列来调用它:

ERROR( "This is an example error in file %s\n", errorString.c_str() )

但我最终得到以下编译错误:

error: expected ‘)’ before ‘errorString’

我应该如何最好地修改我的宏定义来解决这个问题?

4

1 回答 1

1

我不熟悉 ACE,但您似乎正在寻找逗号删除扩展:

#define ERROR(FMT, ...) ACE_DEBUG((LM_ERROR, ACE_TEXT(FMT), ##__VA_ARGS__))

GNU CPP 手册的“可变参数宏”部分中所述,当且仅当使用零变量参数调用宏时,在逗号之间放置##并且__VA_ARGS__具有删除逗号的特殊效果。因此,

ERROR("This is an example error");
ERROR("This is an example error %s", string);

将分别扩展为

ACE_DEBUG((LM_ERROR, ACE_TEXT("This is an example error")));
ACE_DEBUG((LM_ERROR, ACE_TEXT("This is an example error %s"), string));

可能是你想要的(同样,我不知道 ACE)。除非您关心到非常旧的GCC 的可移植性,如在 EGCS 之前的版本中,否则在三个令牌序列中和周围的间距, ## __VA_ARGS__无关紧要。

此功能是一个 GNU 扩展,clang 和任何使用 EDG 前端并启用其 GNU 兼容模式的东西也支持此功能。至关重要的是,据我所知,微软的编译器不支持它。

(因为快到圣诞节了,我还应该提一下,在括号里面加空格会让小耶稣哭泣。)

于 2012-12-22T15:24:29.950 回答