__SYSCALL_DEFINEx 单个宏定义中的多个值
Multiple values in a single macro definition with __SYSCALL_DEFINEx
我试图理解 /include/linux/syscall.h 中的一段代码,其中宏定义似乎有多个值,每个值都用分号分隔:
235 #define __SYSCALL_DEFINEx(x, name, ...) \
236 __diag_push(); \
237 __diag_ignore(GCC, 8, "-Wattribute-alias", \
238 "Type aliasing is used to sanitize syscall arguments");\
239 asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
240 __attribute__((alias(__stringify(__se_sys##name)))); \
241 ALLOW_ERROR_INJECTION(sys##name, ERRNO); \
242 static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
243 asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
244 asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
245 { \
246 long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\
247 __MAP(x,__SC_TEST,__VA_ARGS__); \
248 __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
249 return ret; \
250 } \
251 __diag_pop(); \
252 static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
我以前没见过这个,也找不到任何参考资料。 __SYSCALL_DEFINEx(x, name, ...)
以这种方式定义时会做什么?
where a macro definition seems to have multiple values
宏没有任何值。宏是一种令牌操作结构。当预处理器扩展它时,它将(零个或多个)输入令牌转换为输出令牌。输出标记只需要是有效的标记,它们甚至不需要是有效的 C 代码。例如:
#define foo(t) 1 > 0 t 0 : 1
这是一个完全有效的类似函数的宏定义。当我们写 foo(;)
或 foo(3)
时,预处理器将参数替换为它吐出的标记序列。当然,对于我们提供的参数,结果在语法上是无效的 C。但是 foo(?)
会 导致有效的 C。
序言的目的是解释那些分号没有任何特殊作用。它们只是宏吐出的令牌序列的一部分。该宏旨在用一系列实现系统调用的声明和函数定义来替换自身。函数体中的声明和语句必须以 ;
结尾。仅此而已。
在这种情况下,您看到的不是具有多个值的宏定义,而是跨越多行的宏定义。所以基本上,__SYSCALL_DEFINEx(x, name, ...) 将被它下面的整个代码块替换(请注意,该行末尾的 \ 用于跨越多行,当然,每个代码行应以 ;).
结尾
我试图理解 /include/linux/syscall.h 中的一段代码,其中宏定义似乎有多个值,每个值都用分号分隔:
235 #define __SYSCALL_DEFINEx(x, name, ...) \
236 __diag_push(); \
237 __diag_ignore(GCC, 8, "-Wattribute-alias", \
238 "Type aliasing is used to sanitize syscall arguments");\
239 asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
240 __attribute__((alias(__stringify(__se_sys##name)))); \
241 ALLOW_ERROR_INJECTION(sys##name, ERRNO); \
242 static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\
243 asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
244 asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
245 { \
246 long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__));\
247 __MAP(x,__SC_TEST,__VA_ARGS__); \
248 __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
249 return ret; \
250 } \
251 __diag_pop(); \
252 static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))
我以前没见过这个,也找不到任何参考资料。 __SYSCALL_DEFINEx(x, name, ...)
以这种方式定义时会做什么?
where a macro definition seems to have multiple values
宏没有任何值。宏是一种令牌操作结构。当预处理器扩展它时,它将(零个或多个)输入令牌转换为输出令牌。输出标记只需要是有效的标记,它们甚至不需要是有效的 C 代码。例如:
#define foo(t) 1 > 0 t 0 : 1
这是一个完全有效的类似函数的宏定义。当我们写 foo(;)
或 foo(3)
时,预处理器将参数替换为它吐出的标记序列。当然,对于我们提供的参数,结果在语法上是无效的 C。但是 foo(?)
会 导致有效的 C。
序言的目的是解释那些分号没有任何特殊作用。它们只是宏吐出的令牌序列的一部分。该宏旨在用一系列实现系统调用的声明和函数定义来替换自身。函数体中的声明和语句必须以 ;
结尾。仅此而已。
在这种情况下,您看到的不是具有多个值的宏定义,而是跨越多行的宏定义。所以基本上,__SYSCALL_DEFINEx(x, name, ...) 将被它下面的整个代码块替换(请注意,该行末尾的 \ 用于跨越多行,当然,每个代码行应以 ;).
结尾