Spec-Zone.ru › GCC 4

6.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;
}
— Встроенная функция: size_t __builtin_va_arg_pack_len ()

Эта встроенная функция возвращает количество анонимных аргументов встроенной функции. Она может использоваться только во встроенных функциях, которые всегда встраиваются, никогда не компилируются как отдельная функция, например, таких, которые используют __attribute__ ((__always_inline__)) или __attribute__ ((__gnu_inline__)) extern 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

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Constructing-Calls.html

Spec-Zone.ru

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