Spec-Zone.ru › GCC 9

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, 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, vsscanf, обрабатываются как встроенные функции, за исключением строгого режима ISO C90 (-ansi или -std=c90).

more

Также есть встроенные версии функций 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, modf, 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, 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, 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_. Мы намерены предоставить реализатору библиотеки возможность просто #define каждого стандартного макроса к его встроенному эквиваленту. Аналогичным образом GCC предоставляет встроенные функции fpclassify, isfinite, isinf_sign, isnormal и signbit, используемые с префиксом __builtin_. Встроенные функции isinf и isnan появляются как с, так и без префикса __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 (см. Тип). Аргумент 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, и это ошибка, если такой функции не существует.

Встроенная функция: тип __builtin_complex (real, imag)

Встроенная функция __builtin_complex предоставляется для использования в реализации ISO C11 макросов CMPLXF, CMPLX и CMPLXL. real и imag должны иметь одинаковый тип, вещественный двоичный тип с плавающей точкой, а результат имеет соответствующий комплексный тип с действительной и мнимой частями real и imag. В отличие от ‘real + I * imag’, это работает даже когда речь идёт о бесконечностях, NaN и отрицательных нулях.

Встроенная функция: 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++.

Встроенная функция: 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, контролируется параметром GCC builtin-expect-probability, который по умолчанию равен 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 ();
    }
}
Встроенная функция: 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. Подробнее см. Проверка размера объекта.

Встроенная функция: 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.

Встроенная функция: _Floatnx __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.

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

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

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

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

Возвращает идентификатор группы, рабочей части или вектора OpenACC в зависимости от того, равно ли x 0, 1 или 2.

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

Возвращает размер группы, рабочей части или вектора OpenACC в зависимости от того, равно ли x 0, 1 или 2.

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

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

Spec-Zone.ru

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