- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在分析代码时遇到了以下宏。
#define __COMMAND_HANDLER(name, extra ...) int name(struct command_invocation *cmd, ## extra)
函数 name
作为参数传递给 __COMMAND_HANDLER
但是在代码的其他任何地方都没有这个函数的定义。 cmd 参数的类型 (command_invocation
) 已定义。基本上我无法理解这个宏的功能,因为我找不到函数 name
的定义。 name 是标准 C 库中的某种预定义函数吗?如果未定义 name
,此宏定义是否有意义?
最佳答案
在预处理过程中,预处理器会将所有出现的 __COMMAND_HANDLER(name, extra ...)
宏替换为其主体,替换每次出现的 name
和 extra...
在其正文中添加您指定的标记。
这意味着在这种情况下,无论您为 name
参数输入什么,它都将是一个函数名称,而 extra...
将是它在第一个参数旁边的附加参数一个(struct command_invocation *cmd
)。
例如下面一行:
__COMMAND_HANDLER(foo, int param) {
/* definition */
}
预处理后将是:
int foo(struct command_invocation *cmd, int param) {
/* definition */
}
必须澄清一件重要的事情:extra
和命名变量参数之前的 ##
(使用 extra...
而不是 ...
) 不是 c 的一部分标准,但它们是 GNU extensions .逗号后的 ##
的作用是让您不为变量参数指定任何内容。使用 GCC(使用 -pedantic
标志)编译您的示例,当它按如下方式使用时,您将看到警告消息:
/* The following example will print the following messages:
* warning: ISO C does not permit named variadic macros [-Wvariadic-macros]
* warning: ISO C99 requires at least one argument for the "..." in a variadic
* macro
*/
__COMMAND_HANDLER(bar);
通常 ##
是标记连接的运算符,即将 ##
运算符两侧的两个标记组合成一个。例如:
#include <stdio.h>
#define FOO(name, number) void name##number()
FOO(bar, 1) { puts("I'm first."); }
FOO(bar, 2) { puts("I'm second."); }
int main() {
bar1();
bar2();
return 0;
}
关于c - 难以理解的C宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46108055/
我想模拟这个函数: function getMetaData(key) { var deferred = $q.defer(); var s3 = vm.ini
我是一名优秀的程序员,十分优秀!