13
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))

这是这两个宏的定义;稍后在代码中LOGILOGW以这种方式使用

LOGI("accelerometer: x=%f y=%f z=%f",
                                event.acceleration.x, event.acceleration.y,
                                event.acceleration.z);

这样

LOGW("Unable to eglMakeCurrent");

由于我尽量避免使用复杂的宏,而且#define总的来说,我无法理解这个宏的实际含义。3 点符号在这里的作用是什么?#define稍后在代码中会发生什么变化?

显然我知道这 3 个点是用来表示和不定数量的论点,但我不知道如何阅读这种情况。

4

1 回答 1

16

C99 标准引入了可变参数宏,即可以采用可变数量参数的类似函数的宏。

引用 C 标准的最新草案,第 6.10.3 节:

如果宏定义中的标识符列表不以省略号结尾,则调用类函数宏时的参数数量(包括那些不包含预处理标记的参数)应等于宏定义中的参数数量。否则,调用中的参数应多于宏定义中的参数(不包括...)。应该存在一个终止调用的 ) 预处理令牌。

标识符__VA_ARGS__应仅出现在在参数中使用省略号的类函数宏的替换列表中。

...

如果...在宏定义的标识符列表中有 a ,那么尾随参数,包括任何分隔的逗号预处理标记,将被合并为一个项目:变量 arguments。如此组合的参数数量使得在合并后,参数的数量比宏定义中的参数数量多一(不包括...)。

在下一小节中:

替换列表中出现的标识符__VA_ARGS__应被视为参数,可变参数应形成用于替换它的预处理标记。

So you can invoke LOGI or LOGW with as many arguments as you like, and they'll all be expanded at the place specified in the definition by the reference to __VA_ARGS__.

于 2012-09-15T05:05:46.463 回答