Несколько значений в одном определении макроса с __SYSCALL_DEFINEx - PullRequest
1 голос
/ 25 марта 2019

Я пытаюсь понять фрагмент кода из /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, ...) делает, когда определяется таким образом?

Ответы [ 2 ]

2 голосов
/ 25 марта 2019

, где определение макроса имеет несколько значений

Макрос не имеет значений.Макрос - это конструкция манипуляции токеном.Когда препроцессор расширяет его, он превращает (ноль или более) входных токенов в выходные токены.Выходные токены просто должны быть действительными токенами, они даже не должны быть действительным кодом Си.Например:

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

Это совершенно правильное функциональное определение макроса.Когда мы пишем foo(;) или foo(3), препроцессор подставляет аргумент в последовательность токенов, которую он выплевывает.Конечно, для приведенных нами аргументов результат синтаксически неверен C. Но foo(?) приведет к действительному C.

Смысл этой преамбулы состоял в том, чтобы объяснить, что эти точки с запятой нене делай ничего особенного.Они являются лишь частью последовательности токенов, которую выкладывает макрос.Этот макрос предназначен для замены себя последовательностью объявлений и определений функций, которые реализуют системный вызов.Объявления и операторы в органах функций должны заканчиваться символом ;.Ничего больше.

1 голос
/ 25 марта 2019

В этом случае вы не видите определение макроса с несколькими значениями, вы видите определение макроса, которое занимает несколько строк.Таким образом, в основном, __SYSCALL_DEFINEx (x, name, ...) будет заменен целым блоком кода под ним (обратите внимание, что \ в конце строки предназначен для охвата нескольких строк, и, конечно, каждая строка кода должназаканчиваться на;).

...