Ken*_*Ken 11 c label notation c-preprocessor variadic-macros
#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__))
Run Code Online (Sandbox Code Playgroud)
这是这两个宏的定义; 在后面的代码LOGI,并LOGW使用这种方式
LOGI("accelerometer: x=%f y=%f z=%f",
event.acceleration.x, event.acceleration.y,
event.acceleration.z);
Run Code Online (Sandbox Code Playgroud)
就这样
LOGW("Unable to eglMakeCurrent");
Run Code Online (Sandbox Code Playgroud)
因为我试图避免复杂的宏,#define一般来说,我无法得到这个宏实际意味着什么.这里的3点符号有什么作用?这#define在代码后面有什么变化?
显然我知道3个点用于表示和无限量的参数,但我不知道如何阅读这种情况.
Kei*_*son 15
C99标准引入了可变参数宏,即类似函数的宏,可以采用可变数量的参数.
引用C标准的最新草案,第6.10.3节:
如果宏定义中的标识符列表不以省略号结尾,则在调用类函数宏时,参数的数量(包括那些不包含预处理标记的参数)应等于宏定义中的参数数量.否则,调用中的参数应该多于宏定义中的参数(不包括
...).应存在a)终止调用的预处理令牌.标识符
__VA_ARGS__只能出现在类似函数的宏的替换列表中,该宏在参数中使用省略号表示法.
...
如果
...宏定义中的标识符列表中有一个,则尾随参数(包括任何分隔逗号预处理标记)将合并为一个项:变量参数.如此组合的参数数量使得在合并之后,参数的数量比宏定义中的参数数量多一个(不包括...).
在下一小节中:
__VA_ARGS__替换列表中出现的标识符应被视为参数,并且变量参数应形成用于替换它的预处理标记.
因此,您可以根据需要调用LOGI或LOGW使用尽可能多的参数,并且它们都将通过引用在定义中指定的位置进行扩展__VA_ARGS__.