Spec-Zone.ru › GCC 12

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).

END_OF_DOCUMENT_MARKER

Функции 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_, так и без него.

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 предлагают аналогичную функциональность с более портативным, удобным и безопасным интерфейсом, они рекомендуются вместо них в программах C99 и C++, где GCC их предоставляет как расширение. Подробности см. в разделе Переменная длина.

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

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

Встроенная функция: 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 — это встроенная функция, которая не распознаётся в таких контекстах.

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

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

  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.

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

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

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

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

Вы можете использовать встроенную функцию __builtin_choose_expr для оценки кода в зависимости от значения константного выражения. Эта встроенная функция возвращает 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) может всё ещё вызывать синтаксические ошибки. Это может измениться в будущих версиях.

Встроенная функция: тип __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) обрабатываются как _Complex double для этой цели (или _Complex _Float64 если все типы возвращаемых значений функций одинаковы _Floatn или _Floatnx тип). Если типы возвращаемых значений функций различаются или все являются одинаковым целочисленным типом, вызывается функция, для которой 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__ и возвращает константное целочисленное выражение, равное номеру строки вызова встроенной функции. При использовании в качестве аргумента по умолчанию для функции 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. Значение 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. См. Проверка размера объекта для подробного описания функции.

Встроенная функция: 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. Первые пять целочисленных аргументов должны представлять понятия возможных классов 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_ffs (int x)

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

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

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

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

Возвращает количество младших нулевых битов в 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)

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

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

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

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

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

Встроенная функция: 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, в зависимости от того, 0, 1 или 2 соответственно значение x.

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

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

Далее: Встроенные функции целевых платформ, Предыдущее: Проверка размера объектов, Вверх: Расширения языка C [Содержание][Индекс]

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

Spec-Zone.ru

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