6.5 Создание вызовов функций
Используя встроенные функции, описанные ниже, вы можете записывать аргументы, полученные функцией, и вызывать другую функцию с теми же аргументами, не зная их количество или типы.
Вы также можете записать возвращаемое значение этого вызова функции и позже вернуть это значение, не зная тип данных, который функция пыталась вернуть (пока ваш вызывающий код ожидает этот тип данных).
Однако, эти встроенные функции могут плохо взаимодействовать с некоторыми сложными функциями или другими расширениями языка. Поэтому не рекомендуется использовать их вне очень простых функций, выполняющих только передачу аргументов.
- Встроенная функция: void * __builtin_apply_args ()
-
Эта встроенная функция возвращает указатель на данные, описывающие, как выполнить вызов с теми же аргументами, что и переданы в текущую функцию.
Функция сохраняет указатель на регистр arg, адрес структуры значения и все регистры, которые могут использоваться для передачи аргументов в функцию, в блок памяти, выделенный в стеке. Затем она возвращает адрес этого блока.
- Встроенная функция: void * __builtin_apply (void (*function)(), void *arguments, size_t size)
-
Эта встроенная функция вызывает function с копией параметров, описанных arguments и size.
Значение arguments должно быть значением, возвращенным
__builtin_apply_args. Аргумент size указывает размер данных аргументов стека в байтах.Эта функция возвращает указатель на данные, описывающие, как вернуть любое значение, возвращенное функцией function. Данные сохраняются в блоке памяти, выделенном в стеке.
Вычисление правильного значения для size не всегда просто. Это значение используется
__builtin_applyдля вычисления количества данных, которые должны быть помещены в стек и скопированы из области входных аргументов.
- Встроенная функция: void __builtin_return (void *result)
Эта встроенная функция возвращает значение, описанное result, из содержащей функции. Для result вы должны указать значение, возвращенное
__builtin_apply.
- Встроенная функция: __builtin_va_arg_pack ()
-
Эта встроенная функция представляет все анонимные аргументы встроенной функции. Она может использоваться только во встроенных функциях, которые всегда встраиваются, никогда не компилируются как отдельные функции, такие как те, которые используют
__attribute__ ((__always_inline__))или__attribute__ ((__gnu_inline__))внешние встроенные функции. Она должна передаваться только в качестве последнего аргумента какой-либо другой функции с переменными аргументами. Это полезно для написания небольших оберток встроенных функций для функций с переменными аргументами, когда использование макросов препроцессора нежелательно. Например:extern int myprintf (FILE *f, const char *format, ...); extern inline __attribute__ ((__gnu_inline__)) int myprintf (FILE *f, const char *format, ...) { int r = fprintf (f, "myprintf: "); if (r < 0) return r; int s = fprintf (f, format, __builtin_va_arg_pack ()); if (s < 0) return s; return r + s; }
- Встроенная функция: size_t __builtin_va_arg_pack_len ()
-
Эта встроенная функция возвращает количество анонимных аргументов встроенной функции. Она может использоваться только во встроенных функциях, которые всегда встраиваются, никогда не компилируются как отдельные функции, такие как те, которые используют
__attribute__ ((__always_inline__))или__attribute__ ((__gnu_inline__))внешние встроенные функции. Например, следующее выполняет проверку аргументов во время компиляции или выполнения для оптимизированного кода:#ifdef __OPTIMIZE__ extern inline __attribute__((__gnu_inline__)) int myopen (const char *path, int oflag, ...) { if (__builtin_va_arg_pack_len () > 1) warn_open_too_many_arguments (); if (__builtin_constant_p (oflag)) { if ((oflag & O_CREAT) != 0 && __builtin_va_arg_pack_len () < 1) { warn_open_missing_mode (); return __open_2 (path, oflag); } return open (path, oflag, __builtin_va_arg_pack ()); } if (__builtin_va_arg_pack_len () < 1) return __open_2 (path, oflag); return open (path, oflag, __builtin_va_arg_pack ()); } #endif
Далее: Тип данных, Предыдущее: Вложенные функции, Наверх: Расширения C [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/Constructing-Calls.html