【问题标题】:Multiple values in a single macro definition with __SYSCALL_DEFINEx使用 __SYSCALL_DEFINEx 的单个宏定义中的多个值
【发布时间】:2019-03-25 04:37:34
【问题描述】:

我试图从 /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, ...) 以这种方式定义时会做什么?

【问题讨论】:

    标签: c linux-kernel c-preprocessor


    【解决方案1】:

    宏定义似乎有多个值

    宏没有任何值。宏是令牌操作构造。当预处理器扩展它时,它将(零个或多个)输入标记转换为输出标记。输出标记只需是有效的标记,它们甚至不需要是有效的 C 代码。例如:

    #define foo(t) 1 > 0 t 0 : 1
    

    这是一个完全有效的类函数宏定义。当我们编写 foo(;)foo(3) 时,预处理器会将参数替换为它吐出的令牌序列。当然,对于我们提供的参数,结果在语法上是无效的 C。但是 foo(?) 导致有效的 C。

    前言的重点是解释这些分号没有什么特别的作用。它们只是宏吐出的令牌序列的一部分。该宏旨在用一系列实现系统调用的声明和函数定义来替换自身。函数体中的声明和语句必须以; 结尾。仅此而已。

    【讨论】:

      【解决方案2】:

      在这种情况下,您不会看到具有多个值的宏定义,而是看到跨越多行的宏定义。所以基本上, __SYSCALL_DEFINEx(x, name, ...) 将被它下面的整个代码块替换(注意,行尾的 \ 用于跨越多行,当然,每一行代码都应该以;)结尾。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-04
        • 1970-01-01
        • 2017-02-03
        • 1970-01-01
        • 2021-01-17
        • 1970-01-01
        • 2012-10-04
        • 1970-01-01
        相关资源
        最近更新 更多