Spec-Zone.ru › GCC 13

6.59 Другие встроенные функции, предоставляемые GCC

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

Остальные функции предоставляются в целях оптимизации.

За исключением встроенных функций, имеющих библиотечные эквиваленты, такие как стандартные функции библиотеки C, обсуждаемые ниже, или те, что расширяются до вызовов библиотеки, встроенные функции GCC всегда расширяются встраиваемо и, следовательно, не имеют соответствующих точек входа, и их адрес получить нельзя. Попытка использовать их в выражении, отличном от вызова функции, приводит к ошибке времени компиляции.

GCC включает встроенные версии многих функций из стандартной библиотеки C. Эти функции представлены в двух формах: одна с префиксом __builtin_, а другая — без него. Обе формы имеют одинаковый тип (включая прототип), один и тот же адрес (при взятии адреса) и тот же смысл, что и функции библиотеки C, даже если вы укажете опцию -fno-builtin (см. Параметры управления диалектом C). Многие из этих функций оптимизируются только в определенных случаях; если они не оптимизируются в конкретном случае, вызывается функция библиотеки.

Вне строгого режима ISO C (-ansi, -std=c90, -std=c99 или -std=c11) функции _exit, alloca, bcmp, bzero, dcgettext, dgettext, dremf, dreml, drem, exp10f, exp10l, exp10, ffsll, ffsl, ffs, fprintf_unlocked, fputs_unlocked, gammaf, gammal, gamma, gammaf_r, gammal_r, gamma_r, gettext, index, isascii, j0f, j0l, j0, j1f, j1l, j1, jnf, jnl, jn, lgammaf_r, lgammal_r, lgamma_r, mempcpy, pow10f, pow10l, pow10, printf_unlocked, rindex, roundeven, roundevenf, roundevenl, scalbf, scalbl, scalb, signbit, signbitf, signbitl, signbitd32, signbitd64, signbitd128, significandf, significandl, significand, sincosf, sincosl, sincos, stpcpy, stpncpy, strcasecmp, strdup, strfmon, strncasecmp, strndup, strnlen, toascii, y0f, y0l, y0, y1f, y1l, y1, ynf, ynl и yn могут обрабатываться как встроенные функции. Все эти функции имеют соответствующие версии с префиксом __builtin_, которые могут использоваться даже в строгом режиме C90.

Функции ISO C99 _Exit, acoshf, acoshl, acosh, asinhf, asinhl, asinh, atanhf, atanhl, atanh, cabsf, cabsl, cabs, cacosf, cacoshf, cacoshl, cacosh, cacosl, cacos, cargf, cargl, carg, casinf, casinhf, casinhl, casinh, casinl, casin, catanf, catanhf, catanhl, catanh, catanl, catan, cbrtf, cbrtl, cbrt, ccosf, ccoshf, ccoshl, ccosh, ccosl, ccos, cexpf, cexpl, cexp, cimagf, cimagl, cimag, clogf, clogl, clog, conjf, conjl, conj, copysignf, copysignl, copysign, cpowf, cpowl, cpow, cprojf, cprojl, cproj, crealf, creall, creal, csinf, csinhf, csinhl, csinh, csinl, csin, csqrtf, csqrtl, csqrt, ctanf, ctanhf, ctanhl, ctanh, ctanl, ctan, erfcf, erfcl, erfc, erff, erfl, erf, exp2f, exp2l, exp2, expm1f, expm1l, expm1, fdimf, fdiml, fdim, fmaf, fmal, fmaxf, fmaxl, fmax, fma, fminf, fminl, fmin, hypotf, hypotl, hypot, ilogbf, ilogbl, ilogb, imaxabs, isblank, iswblank, lgammaf, lgammal, lgamma, llabs, llrintf, llrintl, llrint, llroundf, llroundl, llround, log1pf, log1pl, log1p, log2f, log2l, log2, logbf, logbl, logb, lrintf, lrintl, lrint, lroundf, lroundl, lround, nearbyintf, nearbyintl, nearbyint, nextafterf, nextafterl, nextafter, nexttowardf, nexttowardl, nexttoward, remainderf, remainderl, remainder, remquof, remquol, remquo, rintf, rintl, rint, roundf, roundl, round, scalblnf, scalblnl, scalbln, scalbnf, scalbnl, scalbn, snprintf, tgammaf, tgammal, tgamma, truncf, truncl, trunc, vfscanf, vscanf, vsnprintf, обрабатываются как встроенные функции, за исключением строгого режима ISO C90 (-ansi или -std=c90).

Также имеются встроенные версии функций ISO C99 acosf, acosl, asinf, asinl, atan2f, atan2l, atanf, atanl, ceilf, ceill, cosf, coshf, coshl, cosl, expf, expl, fabsf, fabsl, floorf, floorl, fmodf, fmodl, frexpf, frexpl, ldexpf, ldexpl, log10f, log10l, logf, logl, modfl, modff, powf, powl, sinf, sinhf, sinhl, sinl, sqrtf, sqrtl, tanf, tanhf, tanhl и tanl, которые распознаются в любом режиме, так как ISO C90 резервирует эти имена для цели, для которой ISO C99 их использует. Все эти функции имеют соответствующие версии с префиксом __builtin_.

Также имеются встроенные функции __builtin_fabsfn, __builtin_fabsfnx, __builtin_copysignfn и __builtin_copysignfnx, соответствующие функциям TS 18661-3 fabsfn, fabsfnx, copysignfn и copysignfnx, для поддерживаемых типов _Floatn и _Floatnx.

Также имеются функции расширений GNU clog10, clog10f и clog10l, имена которых зарезервированы ISO C99 для будущего использования. Все эти функции имеют версии с префиксом __builtin_.

Функции ISO C94 iswalnum, iswalpha, iswcntrl, iswdigit, iswgraph, iswlower, iswprint, iswpunct, iswspace, iswupper, iswxdigit, towlower и towupper обрабатываются как встроенные, за исключением строгого режима ISO C90 (-ansi или -std=c90).

Функции ISO C90 abort, abs, acos, asin, atan2, atan, calloc, ceil, cosh, cos, exit, exp, fabs, floor, fmod, fprintf, fputs, free, frexp, fscanf, isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit, tolower, toupper, labs, ldexp, log10, log, malloc, memchr, memcmp, memcpy, memset, modf, pow, printf, putchar, puts, realloc, scanf, sinh, sin, snprintf, sprintf, sqrt, sscanf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, tanh, tan, vfprintf, vprintf и vsprintf распознаются как встроенные функции, если не указан -fno-builtin (или -fno-builtin-function для отдельной функции).

Все эти функции имеют соответствующие версии с префиксом __builtin_.

GCC предоставляет встроенные версии макросов сравнения чисел с плавающей точкой ISO C99, которые не генерируют исключений для неупорядоченных операндов. Они имеют те же имена, что и стандартные макросы ( isgreater, isgreaterequal, isless, islessequal, islessgreater, и isunordered) , с префиксом __builtin_. Мы предполагаем, что реализатор библиотеки сможет просто заменить каждый стандартный макрос на его встроенный аналог. Аналогично, GCC предоставляет встроенные функции fpclassify, isfinite, isinf_sign, isnormal и signbit с префиксом __builtin_. Встроенные функции isinf и isnan представлены как с префиксом __builtin_, так и без него. При использовании опции -ffinite-math-only встроенные функции isinf и isnan всегда возвращают 0.

GCC предоставляет встроенные версии функций округления и обработки исключений чисел с плавающей точкой ISO C99 fegetround, feclearexcept и feraiseexcept. Они могут быть недоступны для всех целевых платформ, и, поскольку они требуют тесного взаимодействия с внутренними значениями libc, они могут быть недоступны для всех целевых libc, но в любом случае они будут корректно перенаправлять вызовы на libc.

Эти встроенные функции представлены как с префиксом __builtin_, так и без него.

Встроенная функция: void * __builtin_alloca (size_t size)

Функция __builtin_alloca должна вызываться в рамках блока. Функция выделяет на стеке вызывающей функции объект размером size байт. Объект выравнивается на границе выравнивания стека по умолчанию для целевой платформы, определяемой макросом __BIGGEST_ALIGNMENT__. Функция __builtin_alloca возвращает указатель на первый байт выделенного объекта. Жизненный цикл выделенного объекта завершается непосредственно перед возвратом вызывающей функции к своему вызывающему объекту. Это так даже при вызове __builtin_alloca внутри вложенного блока.

Например, следующая функция выделяет восемь объектов по n байт каждый на стеке, сохраняя указатель на каждый в последовательных элементах массива a. Затем она передает массив функции g, которая может безопасно использовать хранилище, на которое указывает каждый элемент массива.

void f (unsigned n)
{
  void *a [8];
  for (int i = 0; i != 8; ++i)
    a [i] = __builtin_alloca (n);

  g (a, n);   // safe
}

Поскольку функция __builtin_alloca не проверяет свой аргумент, ответственность за обеспечение того, чтобы аргумент не привел к превышению размера стека, лежит на вызывающей функции. Функция __builtin_alloca предоставляет возможность выделять на стеке массивы байтов с верхним пределом, который может быть вычислен во время выполнения. В C99 переменные массивы с переменной длиной предлагают аналогичную функциональность в рамках портативного, более удобного и безопасного интерфейса. Их рекомендуется использовать вместо __builtin_alloca, как в программах C99, так и в C++, где GCC предоставляет их в качестве расширения. Подробнее см. Массивы переменной длины.

Встроенная функция: void * __builtin_alloca_with_align (size_t size, size_t alignment)

Функция __builtin_alloca_with_align должна вызываться в рамках блока. Функция выделяет на стеке вызывающей функции объект размером size байт. Выделенный объект выравнивается на границу, указанную аргументом alignment, единицей измерения которого являются биты (а не байты). Аргумент size должен быть положительным и не превышать предел размера стека. Аргумент alignment должен быть константным целочисленным выражением, которое вычисляется до степени 2, большей или равной CHAR_BIT и меньшей некоторого неопределенного максимума. Вызовы с другими значениями отклоняются с ошибкой, указывающей допустимые границы.

Функция возвращает указатель на первый байт выделенного объекта. Жизненный цикл выделенного объекта заканчивается в конце блока, в котором была вызвана функция. Выделенное хранилище освобождается не позднее, чем непосредственно перед тем, как вызывающая функция возвращается к своему вызывающему объекту, но может быть освобождено в конце блока, в котором была вызвана функция.

Например, в следующей функции вызов g небезопасен, потому что, если overalign не равно нулю, пространство, выделенное __builtin_alloca_with_align, может быть освобождено в конце инструкции if, в которой оно было вызвано.

void f (unsigned n, bool overalign)
{
  void *p;
  if (overalign)
    p = __builtin_alloca_with_align (n, 64 /* bits */);
  else
    p = __builtin_alloc (n);

  g (p, n);   // unsafe
}

Поскольку функция __builtin_alloca_with_align не проверяет свой аргумент size, ответственность за обеспечение того, чтобы аргумент не привел к превышению размера стека, лежит на вызывающей функции. Функция __builtin_alloca_with_align предоставляет возможность выделять на стеке массивы байтов с произвольным выравниванием, с верхним пределом, который может быть вычислен во время выполнения. В C99 переменные массивы с переменной длиной предлагают аналогичную функциональность в рамках портативного, более удобного и безопасного интерфейса. Их рекомендуется использовать вместо __builtin_alloca_with_align, как в программах C99, так и в C++, где GCC предоставляет их в качестве расширения. Подробнее см. Массивы переменной длины.

Встроенная функция: void * __builtin_alloca_with_align_and_max (size_t size, size_t alignment, size_t max_size)

Аналогично __builtin_alloca_with_align, но принимает дополнительный аргумент, указывающий верхнюю границу для size в случае, если его значение не может быть вычислено на этапе компиляции, для использования с -fstack-usage, -Wstack-usage и -Walloca-larger-than. max_size должно быть константным целочисленным выражением. Оно не влияет на генерацию кода и не проверяется на совместимость со значением size.

END_OF_DOCUMENT_MARKER
Встроенная функция: bool __builtin_has_attribute (type-or-expression, attribute)

Функция __builtin_has_attribute возвращает целочисленное константное выражение, равное true, если символ или тип, на который ссылается аргумент type-or-expression, объявлен с атрибутом, указанным во втором аргументе. Для аргумента type-or-expression, не ссылающегося на символ, поскольку атрибуты не применяются к выражениям, встроенная функция рассматривает тип аргумента. Ни один из аргументов не вычисляется. Аргумент type-or-expression подчиняется тем же ограничениям, что и аргумент функции typeof (см. Ссылка на тип с typeof). Аргумент attribute — это имя атрибута, за которым необязательно следует список аргументов, разделенных запятыми, заключённых в скобки. Признаются оба формата имён атрибутов — с и без двойных ведущих и завершающих подчёркиваний. Подробнее см. Синтаксис атрибутов. Если для атрибута, ожидающего один или несколько аргументов, не указано ни одного аргумента, функция возвращает true, если type-or-expression объявлен с этим атрибутом независимо от значений аргументов атрибута. Предоставленные аргументы для атрибута, ожидающего некоторые, проверяются и сопоставляются с предоставленным количеством. Функция возвращает true, если все предоставленные аргументы совпадают. Например, первый вызов функции ниже возвращает true, потому что x объявлен с атрибутом aligned, но второй вызов возвращает false, потому что x объявлен с aligned (8), а не с aligned (4).

__attribute__ ((aligned (8))) int x;
_Static_assert (__builtin_has_attribute (x, aligned), "aligned");
_Static_assert (!__builtin_has_attribute (x, aligned (4)), "aligned (4)");

Из-за ограничения функция __builtin_has_attribute возвращает false для атрибута mode, даже если тип или переменная, на которую ссылается аргумент type-or-expression, были объявлены с ним. Функция также не поддерживается с метками и в C с перечислениями.

Обратите внимание, что в отличие от препроцессорного оператора __has_attribute, подходящего для использования в #if препроцессорных директивах, __builtin_has_attribute является встроенной функцией, которая не распознаётся в таких контекстах.

Встроенная функция: type __builtin_speculation_safe_value (type val, type failval)

Эта встроенная функция может использоваться для снижения рисков небезопасного спекулятивного выполнения. type может быть любым целочисленным типом или любым указательным типом.

  1. Если процессор не выполняет код спекулятивно, то возвращается val.
  2. Если процессор выполняет код спекулятивно, то либо:
    • Функция может приостановить выполнение до тех пор, пока не станет известно, что код больше не выполняется спекулятивно (в этом случае можно вернуть val, как выше); или
    • Функция может использовать зависящее от целевой платформы состояние отслеживания спекуляций, чтобы вернуть failval, когда станет известно, что спекулятивное выполнение ошибочно предсказало операцию условного перехода.

Второй аргумент failval необязателен и по умолчанию равен нулю, если опущен.

GCC определяет препроцессорную макрос __HAVE_BUILTIN_SPECULATION_SAFE_VALUE для платформ, обновлённых для поддержки этой встроенной функции.

Встроенная функция может быть использована в случаях, когда переменная, кажется, используется безопасно, но процессор из-за спекулятивного выполнения временно игнорирует проверки границ. Например, рассмотрим следующую функцию:

int array[500];
int f (unsigned untrusted_index)
{
  if (untrusted_index < 500)
    return array[untrusted_index];
  return 0;
}

Если функция вызывается многократно со значением untrusted_index меньше предела 500, то предсказатель ветвлений научится тому, что блок кода, возвращающий значение, хранящееся в array, будет выполняться. Если функция впоследствии вызывается со значением вне диапазона, она по-прежнему будет пытаться выполнить этот блок кода первой, пока процессор не определит, что прогноз был неверным (процессор размотает все неверные операции в этот момент). Однако, в зависимости от того, как используется результат функции, возможно оставить следы в кэше, которые могут раскрыть, что было хранилось в позиции вне границ. Встроенная функция может обеспечить некоторую защиту от утечки данных таким образом, изменив код на:

int array[500];
int f (unsigned untrusted_index)
{
  if (untrusted_index < 500)
    return array[__builtin_speculation_safe_value (untrusted_index)];
  return 0;
}

Встроенная функция либо заставит выполнение приостановиться до полного разрешения условного перехода, либо позволит спекулятивному выполнению продолжить, но используя 0 вместо untrusted_value , если это превысит предел.

Если доступ к любой ячейке памяти потенциально небезопасен при неверном спекулятивном выполнении, то код можно переписать как

int array[500];
int f (unsigned untrusted_index)
{
  if (untrusted_index < 500)
    return *__builtin_speculation_safe_value (&array[untrusted_index], NULL);
  return 0;
}

что приведёт к использованию указателя NULL для небезопасного случая.

Встроенная функция: int __builtin_types_compatible_p (type1, type2)

Вы можете использовать встроенную функцию __builtin_types_compatible_p для определения того, являются ли два типа одинаковыми.

Эта встроенная функция возвращает 1, если неквалифицированные версии типов type1 и type2 (которые являются типами, а не выражениями) совместимы, и 0 в противном случае. Результат этой встроенной функции может использоваться в целочисленных константных выражениях.

Эта встроенная функция игнорирует квалификаторы верхнего уровня (например, const, volatile). Например, int эквивалентно const int.

Тип int[] и int[5] совместимы. С другой стороны, int и char * не совместимы, даже если размер их типов на конкретной архитектуре одинаков. Также учитывается количество косвенных указаний при определении сходства. Следовательно, short * не аналогичен short **. Кроме того, два типа, определённые с помощью typedef, считаются совместимыми, если их базовые типы совместимы.

Тип enum не считается совместимым с типом enum даже если оба совместимы с одним и тем же целочисленным типом; именно это определяет стандарт C. Например, enum {foo, bar} не подобен enum {hot, dog}.

Обычно эту функцию используют в коде, выполнение которого зависит от типов аргументов. Например:

#define foo(x)                                                  \
  ({                                                           \
    typeof (x) tmp = (x);                                       \
    if (__builtin_types_compatible_p (typeof (x), long double)) \
      tmp = foo_long_double (tmp);                              \
    else if (__builtin_types_compatible_p (typeof (x), double)) \
      tmp = foo_double (tmp);                                   \
    else if (__builtin_types_compatible_p (typeof (x), float))  \
      tmp = foo_float (tmp);                                    \
    else                                                        \
      abort ();                                                 \
    tmp;                                                        \
  })

Примечание: Данный конструкт доступен только для C.

Встроенная функция: type __builtin_call_with_static_chain (call_exp, pointer_exp)

Выражение call_exp должно быть вызовом функции, а выражение pointer_exp должно быть указателем. pointer_exp передаётся в вызов функции в местоположение статической цепи целевой платформы. Результатом встроенной функции является результат вызова функции.

Примечание: Эта встроенная функция доступна только для C. Она может использоваться для вызова лямбда-функций Go из C.

Встроенная функция: type __builtin_choose_expr (const_exp, exp1, exp2)

Вы можете использовать встроенную функцию __builtin_choose_expr для оценки кода в зависимости от значения целочисленного константного выражения const_exp. Эта встроенная функция возвращает exp1, если const_exp отлично от нуля. В противном случае возвращается exp2.

Эта встроенная функция аналогична оператору ‘? :’ в C, за исключением того, что тип возвращаемого выражения не изменяется правилами повышения. Кроме того, встроенная функция не вычисляет невыбранное выражение. Например, если const_exp равно true, exp2 не вычисляется, даже если оно имеет побочные эффекты.

Эта встроенная функция может возвращать lvalue, если выбранный аргумент является lvalue.

Если возвращается exp1, тип возврата совпадает с типом exp1. Аналогично, если возвращается exp2, его тип возврата совпадает с типом exp2.

Пример:

#define foo(x)                                                    \
  __builtin_choose_expr (                                         \
    __builtin_types_compatible_p (typeof (x), double),            \
    foo_double (x),                                               \
    __builtin_choose_expr (                                       \
      __builtin_types_compatible_p (typeof (x), float),           \
      foo_float (x),                                              \
      /* The void expression results in a compile-time error  \
         when assigning the result to something.  */          \
      (void)0))

Примечание: Этот конструкт доступен только для C. Кроме того, неиспользуемое выражение (exp1 или exp2 в зависимости от значения const_exp) может всё ещё генерировать синтаксические ошибки. Это может измениться в будущих версиях.

Встроенная функция: type __builtin_tgmath (functions, arguments)

Встроенная функция __builtin_tgmath, доступная только для C и Objective-C, вызывает функцию, определяемую по правилам <tgmath.h> макросов. Она предназначена для использования в реализациях этих заголовков, чтобы расширения макросов из этого заголовка расширяли каждый из своих аргументов только один раз, чтобы избежать проблем, когда вызовы таких макросов вложены внутри аргументов других вызовов таких макросов; кроме того, это приводит к лучшей диагностике некорректных вызовов <tgmath.h> макросов, чем реализации, использующие другие возможности языка GNU C. Например, pow тип-обобщённый макрос может быть определён как:

#define pow(a, b) __builtin_tgmath (powf, pow, powl, \
                                    cpowf, cpow, cpowl, a, b)

Аргументы __builtin_tgmath — это по меньшей мере два указателя на функции, за которыми следуют аргументы тип-обобщённого макроса (которые будут переданы в качестве аргументов выбранной функции). Все указатели на функции должны быть указателями на прототипированные функции, ни одна из которых не может иметь переменное число аргументов, и все они должны иметь одинаковое количество параметров; количество параметров первой функции определяет, сколько аргументов __builtin_tgmath интерпретируются как указатели на функции, а сколько — как аргументы вызываемой функции.

Типы указанных функций должны быть все различными, но связаны между собой так же, как набор функций, между которыми можно выбирать с помощью макроса в <tgmath.h>. Это означает, что функции параметризованы типом с плавающей точкой t, отличным для каждой такой функции. Типы возвращаемых значений функций могут быть все одного типа, или они могут быть типом t для каждой функции, или они могут быть реальным типом, соответствующим t для каждой функции (если некоторые из типов t — комплексные). Аналогично, для каждой позиции параметра тип параметра в этой позиции может быть всегда одним и тем же типом, или может быть t для каждой функции (этот случай должен применяться по крайней мере для одной позиции параметра), или может быть реальным типом, соответствующим t для каждой функции.

Используются стандартные правила для <tgmath.h> макросов, чтобы найти общий тип u из типов аргументов для параметров, типы которых меняются между функциями; комплексные целочисленные типы (расширение GNU) обрабатываются как комплексный тип, соответствующий реально-плавающему типу, который был бы выбран для соответствующего целочисленного типа. Если типы возвращаемых значений функций меняются или являются все одним целым типом, вызывается функция, для которой t равно u, и это ошибка, если такой функции нет. Если типы возвращаемых значений функций — все один и тот же тип с плавающей точкой, тип-обобщённый макрос считается одним из тех, что из TS 18661, которые округляют результат до более узкого типа; если существует функция, для которой t равно u, она вызывается, а в противном случае — первая функция, если таковая есть, для которой t имеет по меньшей мере диапазон и точность u, вызывается, и это ошибка, если такой функции нет.

Встроенная функция: int __builtin_constant_p (exp)

Вы можете использовать встроенную функцию __builtin_constant_p, чтобы определить, известно ли значение как константа во время компиляции, и поэтому GCC может выполнить условное подстановку констант в выражения, включающие это значение. Аргументом функции является значение, которое нужно проверить. Функция возвращает целое число 1, если аргумент известен как константа во время компиляции, и 0, если он не известен как константа во время компиляции. Возврат 0 не указывает, что значение не является константой, а только то, что GCC не может доказать, что это константа с указанным значением опции -O.

Обычно вы используете эту функцию в встроенном приложении, где память — критический ресурс. Если у вас есть какое-то сложное вычисление, вы можете захотеть, чтобы оно было сложено, если оно включает константы, но вам нужно вызвать функцию, если это не так. Например:

#define Scale_Value(X)      \
  (__builtin_constant_p (X) \
  ? ((X) * SCALE + OFFSET) : Scale (X))

Вы можете использовать эту встроенную функцию как в макросе, так и во встроенной функции. Однако, если вы используете её во встроенной функции и передаёте аргумент функции в качестве аргумента встроенной функции, GCC никогда не возвращает 1 при вызове встроенной функции со строковой константой или составным литералом (см. Составные литералы) и не возвращает 1 при передаче числовой константы в встроенную функцию, если вы не укажете опцию -O.

Вы также можете использовать __builtin_constant_p в инициализаторах для статических данных. Например, вы можете написать

static const int table[] = {
   __builtin_constant_p (EXPRESSION) ? (EXPRESSION) : -1,
   /* … */
};

Это допустимый инициализатор, даже если EXPRESSION не является выражением константы, включая случай, когда __builtin_constant_p возвращает 1, потому что EXPRESSION можно сложить в константу, но EXPRESSION содержит операнды, которые в противном случае не допускаются в статическом инициализаторе (например, 0 && foo ()). GCC должен быть более консервативным при оценке встроенной функции в этом случае, потому что у него нет возможности выполнить оптимизацию.

Встроенная функция: bool __builtin_is_constant_evaluated (void)

Функция __builtin_is_constant_evaluated доступна только в C++. Встроенная функция предназначена для использования реализациями std::is_constant_evaluated функции C++. Программы должны использовать последнюю функцию вместо прямого вызова встроенной.

Основной случай использования встроенной функции — определить, вызывается ли constexpr функция в constexpr контексте. Вызов функции оценивается как ядро выражения константы со значением true, если и только если он встречается внутри оценки выражения или преобразования, которые явно оцениваются как константы, как определено в стандарте C++. К явным контекстам оценки констант относятся выражения-константы, условия constexpr if операторов, выражения ограничений и инициализаторы переменных, используемых в выражениях констант. Более подробную информацию см. в последней редакции стандарта C++.

Встроенная функция: void __builtin_clear_padding (ptr)

Встроенная функция __builtin_clear_padding очищает биты заполнения внутри представления объекта, на который указывает ptr, который должен быть указателем. Представление значения объекта не изменяется. Предполагается, что тип объекта — тип, на который указывает указатель. Внутри объединения очищаются только биты, которые являются битами заполнения для всех членов объединения.

Эта встроенная функция полезна, если биты заполнения объекта могут иметь неопределённые значения, и представление объекта нужно сравнивать по битам с каким-либо другим объектом, например, для атомарных операций.

Для C++, аргумент ptr должен быть указателем на тип, допускающий тривиальную копирование, если аргумент — адрес переменной или параметра, иначе неизвестно, не является ли тип просто базовым классом, биты заполнения которого повторно используются или выстроены иначе в производном классе.

Встроенная функция: type __builtin_bit_cast (type, arg)

Функция __builtin_bit_cast доступна только в C++. Встроенная функция предназначена для использования реализациями std::bit_cast шаблонной функции C++. Программы должны использовать последнюю функцию вместо прямого вызова встроенной.

Эта встроенная функция позволяет переинтерпретировать биты аргумента arg так, как если бы он имел тип type. type и тип аргумента arg должны быть типами, допускающими тривиальную копирование, с одинаковым размером. При явной оценке констант она выполняет дополнительную диагностику, необходимую для std::bit_cast, и возвращает выражение константы, если arg является выражением константы. Более подробную информацию см. в последней редакции стандарта C++.

Встроенная функция: long __builtin_expect (long exp, long c)

Вы можете использовать __builtin_expect для предоставления компилятору информации о прогнозировании ветвлений. В общем случае вы должны отдавать предпочтение фактической обратной связи профиля для этого (-fprofile-arcs), поскольку программисты печально известны тем, что плохо предсказывают реальное поведение своих программ. Однако существуют приложения, в которых эти данные трудно собрать.

Возвращаемое значение — значение exp, которое должно быть целочисленным выражением. Семантика встроенной функции заключается в том, что ожидается, что exp == c. Например:

if (__builtin_expect (x, 0))
  foo ();

указывает, что мы не ожидаем вызова foo, так как мы ожидаем, что x будет равно нулю. Поскольку вы ограничены целочисленными выражениями для exp, вы должны использовать конструкции, такие как

if (__builtin_expect (ptr != NULL, 1))
  foo (*ptr);

при тестировании указателей или значений с плавающей точкой.

Для целей оптимизации прогнозирования ветвлений вероятность того, что выражение __builtin_expect равно true, контролируется параметром builtin-expect-probability GCC, который по умолчанию равен 90%.

Вы также можете использовать __builtin_expect_with_probability для явного назначения значения вероятности отдельным выражениям. Если встроенная функция используется в цикле, указанная вероятность повлияет на ожидаемое число итераций, выполняемых оптимизациями цикла.

Встроенная функция: long __builtin_expect_with_probability

(long exp, long c, double probability)

Эта функция имеет ту же семантику, что и __builtin_expect, но вызывающая функция предоставляет ожидаемую вероятность того, что exp == c. Последний аргумент, probability, — значение с плавающей запятой в диапазоне от 0,0 до 1,0 включительно. Аргумент probability должен быть константным выражением с плавающей запятой.

Встроенная функция: void __builtin_trap (void)

Эта функция вызывает ненормальное завершение программы. GCC реализует эту функцию с помощью зависящего от платформы механизма (например, преднамеренного выполнения недопустимой инструкции) или вызова abort. Использованный механизм может изменяться в разных релизах, поэтому вы не должны полагаться на какую-либо конкретную реализацию.

Встроенная функция: void __builtin_unreachable (void)

Если поток управления достигает точки __builtin_unreachable, поведение программы не определено. Это полезно в ситуациях, когда компилятор не может определить недостижимость кода.

Один из таких случаев — сразу после оператора asm, который либо никогда не завершается, либо передаёт управление в другое место и никогда не возвращается. В этом примере, без __builtin_unreachable, GCC выдает предупреждение о том, что управление достигает конца функции, не возвращающей значение. Также генерируется код для возврата после asm.

int f (int c, int v)
{
  if (c)
    {
      return v;
    }
  else
    {
      asm("jmp error_handler");
      __builtin_unreachable ();
    }
}

Поскольку оператор asm безусловно передаёт управление за пределы функции, управление никогда не достигает конца тела функции. __builtin_unreachable фактически недостижима и сообщает об этом компилятору.

Другое применение __builtin_unreachable — следование за вызовом функции, которая никогда не возвращается, но не объявлена __attribute__((noreturn)), как в этом примере:

void function_that_never_returns (void);

int g (int c)
{
  if (c)
    {
      return 1;
    }
  else
    {
      function_that_never_returns ();
      __builtin_unreachable ();
    }
}
Встроенная функция: type __builtin_assoc_barrier (type expr)

Эта встроенная функция препятствует повторной ассоциации выражения с плавающей точкой expr с выражениями, использующими возвращаемое значение встроенной функции. Само выражение expr может быть переупорядочено, и всё выражение expr может быть переупорядочено с операндами после барьера. Барьер актуален только когда -fassociative-math активен, так как в противном случае арифметика с плавающей точкой не рассматривается как ассоциативная.

float x0 = a + b - b;
float x1 = __builtin_assoc_barrier(a + b) - b;

означает, что с -fassociative-math, x0 может быть оптимизирован до x0 = a, но x1 не может.

Встроенная функция: void * __builtin_assume_aligned (const void *exp, size_t align, ...)

Эта функция возвращает свой первый аргумент и позволяет компилятору предположить, что возвращаемый указатель выровнен по крайней мере на align байт. У этой встроенной функции может быть два или три аргумента; если три, третий аргумент должен иметь целочисленный тип, и если он не равен нулю, это означает смещение невыравнивания. Например:

void *x = __builtin_assume_aligned (arg, 16);

означает, что компилятор может предположить, что x, установленный в arg, выровнен по крайней мере на 16 байт, в то время как:

void *x = __builtin_assume_aligned (arg, 32, 8);

означает, что компилятор может предположить для x, установленного в arg, что (char *) x - 8 выровнен по крайней мере на 32 байта.

Встроенная функция: int __builtin_LINE ()

Эта функция эквивалентна препроцессорной макрокоманде __LINE__ и возвращает константное целочисленное выражение, которое оценивается в строку вызова встроенной функции. При использовании в качестве аргумента по умолчанию C++ для функции F она возвращает номер строки вызова F.

Встроенная функция: const char * __builtin_FUNCTION ()

Эта функция эквивалентна символу __FUNCTION__ и возвращает константный адрес, указывающий на имя функции, из которой был вызван встроенный элемент, или пустую строку, если вызов не находится в области видимости функции. При использовании в качестве аргумента по умолчанию C++ для функции F она возвращает имя вызывающей F функции или пустую строку, если вызов не находится в области видимости функции.

Встроенная функция: const char * __builtin_FILE ()

Эта функция эквивалентна препроцессорной макрокоманде __FILE__ и возвращает константный адрес, указывающий на имя файла, содержащего вызов встроенного элемента, или пустую строку, если вызов не находится в области видимости функции. При использовании в качестве аргумента по умолчанию C++ для функции F она возвращает имя файла вызова F или пустую строку, если вызов не находится в области видимости функции.

Например, в следующем примере каждый вызов функции foo выведет строку, похожую на "file.c:123: foo: message", с именем файла и номером строки вызова printf, именем функции foo, за которым следует слово message.

const char*
function (const char *func = __builtin_FUNCTION ())
{
  return func;
}

void foo (void)
{
  printf ("%s:%i: %s: message\n", file (), line (), function ());
}
Встроенная функция: void __builtin___clear_cache (void *begin, void *end)

Эта функция используется для сброса кэша инструкций процессора для области памяти между begin (включительно) и end (исключительно). Некоторые платформы требуют сброса кэша инструкций после изменения памяти, содержащей код, для получения детерминированного поведения.

Если целевая платформа не требует сброса кэша инструкций, __builtin___clear_cache не имеет эффекта. В противном случае либо генерируются инструкции для сброса кэша инструкций, либо делается вызов функции __clear_cache в libgcc.

Встроенная функция: void __builtin_prefetch (const void *addr, ...)

Эта функция используется для минимизации задержки промаха кэша, перемещая данные в кэш перед доступом. Вы можете вставлять вызовы __builtin_prefetch в код, для которого известны адреса данных в памяти, которые вероятно будут скоро обработаны. Если платформа их поддерживает, генерируются инструкции предварительной выборки данных. Если предварительная выборка выполняется достаточно рано перед доступом, то данные будут в кэше к моменту доступа.

Значение addr — адрес памяти для предварительной выборки. Есть два необязательных аргумента, rw и locality. Значение rw — константа времени компиляции 1 или 0; 1 означает, что предварительная выборка готовит запись в адрес памяти, а 0 (значение по умолчанию) означает, что предварительная выборка готовит чтение. Значение locality должно быть константой времени компиляции целого числа от нуля до трёх. Значение 0 означает, что данные не обладают временной локальностью, поэтому их не нужно оставлять в кэше после доступа. Значение 3 означает, что данные обладают высокой степенью временной локальности и должны оставаться во всех уровнях кэша, насколько возможно. Значения 1 и 2 соответственно означают низкую или среднюю степень временной локальности. Значение по умолчанию — 3.

for (i = 0; i < n; i++)
  {
    a[i] = a[i] + b[i];
    __builtin_prefetch (&a[i+j], 1, 1);
    __builtin_prefetch (&b[i+j], 0, 1);
    /* … */
  }

Предварительная выборка данных не генерирует ошибки, если addr недействителен, но само выражение адреса должно быть действительным. Например, предварительная выборка p->next не вызывает ошибки, если p->next не является действительным адресом, но оценка вызывает ошибку, если p не является действительным адресом.

Если платформа не поддерживает предварительную выборку данных, выражение адреса оценивается, если оно содержит побочные эффекты, но другой код не генерируется, и GCC не выдает предупреждение.

Встроенная функция: size_t __builtin_object_size (const void * ptr, int type)

Возвращает оценочный размер объекта, на который указывает ptr. Подробное описание функции см. в разделе Проверка размера объектов.

Встроенная функция: size_t __builtin_dynamic_object_size (const void * ptr, int type)

Аналогично __builtin_object_size, за исключением того, что возвращаемое значение не должно быть константой. Подробное описание функции см. в разделе Проверка размера объектов.

END_OF_DOCUMENT_MARKER
Встроенная функция: double __builtin_huge_val (void)

Возвращает положительную бесконечность, если поддерживается форматом с плавающей точкой, иначе DBL_MAX. Эта функция подходит для реализации макроса ISO C HUGE_VAL.

Встроенная функция: float __builtin_huge_valf (void)

Аналогично __builtin_huge_val, за исключением того, что тип возвращаемого значения float.

Встроенная функция: long double __builtin_huge_vall (void)

Аналогично __builtin_huge_val, за исключением того, что тип возвращаемого значения long double.

Встроенная функция: _Floatn __builtin_huge_valfn (void)

Аналогично __builtin_huge_val, за исключением того, что тип возвращаемого значения _Floatn.

Встроенная функция: _Floatnx __builtin_huge_valfnx (void)

Аналогично __builtin_huge_val, за исключением того, что тип возвращаемого значения _Floatnx.

Встроенная функция: int __builtin_fpclassify (int, int, int, int, int, ...)

Эта встроенная функция реализует функциональность C99 fpclassify. Первые пять аргументов типа int должны представлять собой представление целевой библиотеки о возможных классах FP и используются для возвращаемых значений. Они должны быть константными значениями и должны появляться в этом порядке: FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL и FP_ZERO. Многоточие предназначено для ровно одного значения с плавающей точкой для классификации. GCC обрабатывает последний аргумент как универсальный по типу, что означает, что он не выполняет неявное преобразование типа float в double.

Встроенная функция: double __builtin_inf (void)

Аналогично __builtin_huge_val, за исключением того, что генерируется предупреждение, если целевой формат с плавающей точкой не поддерживает бесконечности.

Встроенная функция: _Decimal32 __builtin_infd32 (void)

Аналогично __builtin_inf, за исключением того, что тип возвращаемого значения _Decimal32.

Встроенная функция: _Decimal64 __builtin_infd64 (void)

Аналогично __builtin_inf, за исключением того, что тип возвращаемого значения _Decimal64.

Встроенная функция: _Decimal128 __builtin_infd128 (void)

Аналогично __builtin_inf, за исключением того, что тип возвращаемого значения _Decimal128.

Встроенная функция: float __builtin_inff (void)

Аналогично __builtin_inf, за исключением того, что тип возвращаемого значения float. Эта функция подходит для реализации макроса ISO C99 INFINITY.

Встроенная функция: long double __builtin_infl (void)

Аналогично __builtin_inf, за исключением того, что тип возвращаемого значения long double.

Встроенная функция: _Floatn __builtin_inffn (void)

Аналогично __builtin_inf, за исключением того, что тип возвращаемого значения _Floatn.

Встроенная функция: _Floatn __builtin_inffnx (void)

Аналогично __builtin_inf, за исключением того, что тип возвращаемого значения _Floatnx.

Встроенная функция: int __builtin_isinf_sign (...)

Аналогично isinf, за исключением того, что возвращаемое значение равно -1 для аргумента -Inf и 1 для аргумента +Inf. Обратите внимание, что хотя список параметров представляет собой многоточие, эта функция принимает только один аргумент с плавающей точкой. GCC обрабатывает этот параметр как универсальный по типу, что означает, что он не выполняет неявное преобразование типа float в double.

Встроенная функция: double __builtin_nan (const char *str)

Это реализация функции ISO C99 nan.

Поскольку ISO C99 определяет эту функцию в терминах strtod, которые мы не реализуем, необходимо описание разбора. Строка разбирается так же, как и strtol; то есть, основание распознается по префиксам «0» или «0x». Разобранное число помещается в мантиссу таким образом, что наименее значимый бит числа находится в наименее значимом бите мантиссы. Число усекается, чтобы соответствовать предоставленному полю мантиссы. Мантисса принудительно устанавливается в значение «тихое NaN».

Эта функция, если ей передается строковая константа, которая была бы полностью обработана strtol, вычисляется достаточно рано, чтобы считаться константой времени компиляции.

Встроенная функция: _Decimal32 __builtin_nand32 (const char *str)

Аналогично __builtin_nan, за исключением того, что тип возвращаемого значения _Decimal32.

Встроенная функция: _Decimal64 __builtin_nand64 (const char *str)

Аналогично __builtin_nan, за исключением того, что тип возвращаемого значения _Decimal64.

Встроенная функция: _Decimal128 __builtin_nand128 (const char *str)

Аналогично __builtin_nan, за исключением того, что тип возвращаемого значения _Decimal128.

Встроенная функция: float __builtin_nanf (const char *str)

Аналогично __builtin_nan, за исключением того, что тип возвращаемого значения float.

Встроенная функция: long double __builtin_nanl (const char *str)

Аналогично __builtin_nan, за исключением того, что тип возвращаемого значения long double.

Встроенная функция: _Floatn __builtin_nanfn (const char *str)

Аналогично __builtin_nan, за исключением того, что тип возвращаемого значения _Floatn.

Встроенная функция: _Floatnx __builtin_nanfnx (const char *str)

Аналогично __builtin_nan, за исключением того, что тип возвращаемого значения _Floatnx.

Встроенная функция: double __builtin_nans (const char *str)

Аналогично __builtin_nan, за исключением того, что мантисса принудительно устанавливается в значение «сигнальное NaN». Функция nans предложена WG14 N965.

Встроенная функция: _Decimal32 __builtin_nansd32 (const char *str)

Аналогично __builtin_nans, за исключением того, что тип возвращаемого значения _Decimal32.

Встроенная функция: _Decimal64 __builtin_nansd64 (const char *str)

Аналогично __builtin_nans, за исключением того, что возвращаемый тип — _Decimal64.

Встроенная функция: _Decimal128 __builtin_nansd128 (const char *str)

Аналогично __builtin_nans, за исключением того, что возвращаемый тип — _Decimal128.

Встроенная функция: float __builtin_nansf (const char *str)

Аналогично __builtin_nans, за исключением того, что возвращаемый тип — float.

Встроенная функция: long double __builtin_nansl (const char *str)

Аналогично __builtin_nans, за исключением того, что возвращаемый тип — long double.

Встроенная функция: _Floatn __builtin_nansfn (const char *str)

Аналогично __builtin_nans, за исключением того, что возвращаемый тип — _Floatn.

Встроенная функция: _Floatnx __builtin_nansfnx (const char *str)

Аналогично __builtin_nans, за исключением того, что возвращаемый тип — _Floatnx.

Встроенная функция: int __builtin_issignaling (...)

Возвращает ненулевое значение, если аргумент является сигнализирующим NaN, и ноль в противном случае. Обратите внимание, что хотя список параметров является многоточием, эта функция принимает только один аргумент с плавающей точкой. GCC обрабатывает этот параметр как универсальный по типу, что означает, что он не выполняет стандартное повышение типа от float до double. Эта встроенная функция может работать даже без параметра -fsignaling-nans, хотя, если сигнализирующий NaN вычисляется, сохраняется или передается как аргумент какой-либо функции, отличной от этой встроенной в текущем трансляционном блоке, безопаснее использовать -fsignaling-nans. С параметром -ffinite-math-only эта встроенная функция всегда будет возвращать 0.

Встроенная функция: int __builtin_ffs (int x)

Возвращает единицу плюс индекс наименее значимого 1-бита x, или, если x равно нулю, возвращает ноль.

Встроенная функция: int __builtin_clz (unsigned int x)

Возвращает количество старших 0-битов в x, начиная с наиболее значимого бита. Если x равно 0, результат не определен.

Встроенная функция: int __builtin_ctz (unsigned int x)

Возвращает количество младших 0-битов в x, начиная с наименее значимого бита. Если x равно 0, результат не определен.

Встроенная функция: int __builtin_clrsb (int x)

Возвращает количество старших избыточных битов знака в x, т.е. количество битов после наиболее значимого бита, которые идентичны ему. Нет никаких особых случаев для 0 или других значений.

Встроенная функция: int __builtin_popcount (unsigned int x)

Возвращает количество 1-битов в x.

Встроенная функция: int __builtin_parity (unsigned int x)

Возвращает четность x, т.е. количество 1-битов в x по модулю 2.

Встроенная функция: int __builtin_ffsl (long)

Аналогично __builtin_ffs, за исключением того, что тип аргумента — long.

Встроенная функция: int __builtin_clzl (unsigned long)

Аналогично __builtin_clz, за исключением того, что тип аргумента — unsigned long.

Встроенная функция: int __builtin_ctzl (unsigned long)

Аналогично __builtin_ctz, за исключением того, что тип аргумента — unsigned long.

Встроенная функция: int __builtin_clrsbl (long)

Аналогично __builtin_clrsb, за исключением того, что тип аргумента — long.

Встроенная функция: int __builtin_popcountl (unsigned long)

Аналогично __builtin_popcount, за исключением того, что тип аргумента — unsigned long.

Встроенная функция: int __builtin_parityl (unsigned long)

Аналогично __builtin_parity, за исключением того, что тип аргумента — unsigned long.

Встроенная функция: int __builtin_ffsll (long long)

Аналогично __builtin_ffs, за исключением того, что тип аргумента — long long.

Встроенная функция: int __builtin_clzll (unsigned long long)

Аналогично __builtin_clz, за исключением того, что тип аргумента — unsigned long long.

Встроенная функция: int __builtin_ctzll (unsigned long long)

Аналогично __builtin_ctz, за исключением того, что тип аргумента — unsigned long long.

Встроенная функция: int __builtin_clrsbll (long long)

Аналогично __builtin_clrsb, за исключением того, что тип аргумента — long long.

Встроенная функция: int __builtin_popcountll (unsigned long long)

Аналогично __builtin_popcount, за исключением того, что тип аргумента — unsigned long long.

Встроенная функция: int __builtin_parityll (unsigned long long)

Аналогично __builtin_parity, за исключением того, что тип аргумента — unsigned long long.

Встроенная функция: double __builtin_powi (double, int)
Встроенная функция: float __builtin_powif (float, int)
Встроенная функция: long double __builtin_powil (long double, int)

Возвращает первый аргумент, возведенный в степень второго. В отличие от функции pow никаких гарантий относительно точности и округления не дается.

Встроенная функция: uint16_t __builtin_bswap16 (uint16_t x)

Возвращает x с изменённым порядком байтов; например, 0xaabb становится 0xbbaa. Байтом здесь всегда является ровно 8 бит.

Встроенная функция: uint32_t __builtin_bswap32 (uint32_t x)

Аналогично __builtin_bswap16, за исключением того, что аргумент и возвращаемое значение являются 32-битными.

Встроенная функция: uint64_t __builtin_bswap64 (uint64_t x)

Аналогично __builtin_bswap32, за исключением того, что аргумент и возвращаемое значение являются 64-битными.

Встроенная функция: uint128_t __builtin_bswap128 (uint128_t x)

Аналогично __builtin_bswap64, за исключением того, что аргумент и возвращаемое значение являются 128-битными. Поддерживается только на целевых платформах, где поддерживаются 128-битные типы.

Встроенная функция: Pmode __builtin_extend_pointer (void * x)

На целевых платформах, где размер видимого пользователю указателя меньше размера фактического адреса аппаратного обеспечения, эта функция возвращает расширенный пользовательский указатель. Целевые платформы, где это справедливо, включают режим ILP32 на x86_64 или Aarch64. Эта функция в основном полезна при написании кода встроенного языка ассемблера.

Встроенная функция: int __builtin_goacc_parlevel_id (int x)

Возвращает идентификатор openacc gang, worker или vector в зависимости от того, является ли x 0, 1 или 2.

Встроенная функция: int __builtin_goacc_parlevel_size (int x)

Возвращает размер openacc gang, worker или vector в зависимости от того, является ли x 0, 1 или 2.

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gcc/Other-Builtins.html

Spec-Zone.ru

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