7.5 Формирование вызовов функций
Используя описанные ниже встроенные функции, можно сохранить аргументы, полученные функцией, и вызвать другую функцию с теми же аргументами, не зная их количества и типов.
Можно также сохранить возвращаемое значение этого вызова функции, а затем вернуть его, не зная, какой тип данных пыталась вернуть функция (при условии, что вызывающая функция ожидает этот тип данных).
Однако эти встроенные функции могут некорректно взаимодействовать с некоторыми сложными возможностями языка или другими его расширениями. Поэтому их не рекомендуется использовать вне очень простых функций, которые лишь передают свои аргументы дальше.
-
Встроенная функция:
void *__builtin_apply_args() -
Эта встроенная функция возвращает указатель на данные, описывающие способ выполнения вызова с теми же аргументами, что были переданы текущей функции.
Функция сохраняет регистр указателя аргументов, адрес значения структуры и все регистры, которые могут использоваться для передачи аргументов функции, в блок памяти, выделенный в стеке. Затем она возвращает адрес этого блока.
-
Встроенная функция:
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 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; }
-
Встроенная функция:
int__builtin_va_arg_pack_len() -
Эта встроенная функция возвращает количество анонимных аргументов встроенной функции. Её можно использовать только во встроенных функциях, которые всегда встраиваются и никогда не компилируются как отдельные функции, например в тех, где используются
__attribute__ ((__always_inline__))или__attribute__ ((__gnu_inline__))extern inline-функции. Например, следующий код выполняет проверку аргументов open во время компоновки или выполнения для оптимизированного кода:#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
-
Встроенная функция:
type__builtin_call_with_static_chain(call_exp, pointer_exp) -
Выражение call_exp должно быть вызовом функции, а выражение pointer_exp — указателем. pointer_exp передаётся в вызов функции в расположении статической цепочки целевой платформы. Результатом встроенной функции является результат вызова функции.
Примечание: Эта встроенная функция доступна только для C. Её можно использовать для вызова замыканий Go из C.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-15.3.0/gcc/Constructing-Calls.html