C中的#define有三个点

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__替换列表中出现的标识符应被视为参数,并且变量参数应形成用于替换它的预处理标记.

因此,您可以根据需要调用LOGILOGW使用尽可能多的参数,并且它们都将通过引用在定义中指定的位置进行扩展__VA_ARGS__.