Spec-Zone.ru › GCC 7

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API