6.59 Другие встроенные функции, предоставляемые GCC
GCC предоставляет большое количество встроенных функций помимо упомянутых выше. Некоторые из них используются во внутренней обработке исключений или списков аргументов переменной длины и не документированы здесь, так как они могут время от времени изменяться; мы не рекомендуем их общее использование.
Остальные функции предоставляются в целях оптимизации.
За исключением встроенных функций, имеющих библиотечные эквиваленты, такие как стандартные функции библиотеки C, обсуждаемые ниже, или те, что расширяются до вызовов библиотеки, встроенные функции GCC всегда расширяются встраиваемо и, следовательно, не имеют соответствующих точек входа, и их адрес получить нельзя. Попытка использовать их в выражении, отличном от вызова функции, приводит к ошибке времени компиляции.
GCC включает встроенные версии многих функций из стандартной библиотеки C. Эти функции представлены в двух формах: одна с префиксом __builtin_, а другая — без него. Обе формы имеют одинаковый тип (включая прототип), один и тот же адрес (при взятии адреса) и тот же смысл, что и функции библиотеки C, даже если вы укажете опцию -fno-builtin (см. Параметры управления диалектом C). Многие из этих функций оптимизируются только в определенных случаях; если они не оптимизируются в конкретном случае, вызывается функция библиотеки.
Вне строгого режима ISO C (-ansi, -std=c90, -std=c99 или -std=c11) функции _exit, alloca, bcmp, bzero, dcgettext, dgettext, dremf, dreml, drem, exp10f, exp10l, exp10, ffsll, ffsl, ffs, fprintf_unlocked, fputs_unlocked, gammaf, gammal, gamma, gammaf_r, gammal_r, gamma_r, gettext, index, isascii, j0f, j0l, j0, j1f, j1l, j1, jnf, jnl, jn, lgammaf_r, lgammal_r, lgamma_r, mempcpy, pow10f, pow10l, pow10, printf_unlocked, rindex, roundeven, roundevenf, roundevenl, scalbf, scalbl, scalb, signbit, signbitf, signbitl, signbitd32, signbitd64, signbitd128, significandf, significandl, significand, sincosf, sincosl, sincos, stpcpy, stpncpy, strcasecmp, strdup, strfmon, strncasecmp, strndup, strnlen, toascii, y0f, y0l, y0, y1f, y1l, y1, ynf, ynl и yn могут обрабатываться как встроенные функции. Все эти функции имеют соответствующие версии с префиксом __builtin_, которые могут использоваться даже в строгом режиме C90.
Функции ISO C99 _Exit, acoshf, acoshl, acosh, asinhf, asinhl, asinh, atanhf, atanhl, atanh, cabsf, cabsl, cabs, cacosf, cacoshf, cacoshl, cacosh, cacosl, cacos, cargf, cargl, carg, casinf, casinhf, casinhl, casinh, casinl, casin, catanf, catanhf, catanhl, catanh, catanl, catan, cbrtf, cbrtl, cbrt, ccosf, ccoshf, ccoshl, ccosh, ccosl, ccos, cexpf, cexpl, cexp, cimagf, cimagl, cimag, clogf, clogl, clog, conjf, conjl, conj, copysignf, copysignl, copysign, cpowf, cpowl, cpow, cprojf, cprojl, cproj, crealf, creall, creal, csinf, csinhf, csinhl, csinh, csinl, csin, csqrtf, csqrtl, csqrt, ctanf, ctanhf, ctanhl, ctanh, ctanl, ctan, erfcf, erfcl, erfc, erff, erfl, erf, exp2f, exp2l, exp2, expm1f, expm1l, expm1, fdimf, fdiml, fdim, fmaf, fmal, fmaxf, fmaxl, fmax, fma, fminf, fminl, fmin, hypotf, hypotl, hypot, ilogbf, ilogbl, ilogb, imaxabs, isblank, iswblank, lgammaf, lgammal, lgamma, llabs, llrintf, llrintl, llrint, llroundf, llroundl, llround, log1pf, log1pl, log1p, log2f, log2l, log2, logbf, logbl, logb, lrintf, lrintl, lrint, lroundf, lroundl, lround, nearbyintf, nearbyintl, nearbyint, nextafterf, nextafterl, nextafter, nexttowardf, nexttowardl, nexttoward, remainderf, remainderl, remainder, remquof, remquol, remquo, rintf, rintl, rint, roundf, roundl, round, scalblnf, scalblnl, scalbln, scalbnf, scalbnl, scalbn, snprintf, tgammaf, tgammal, tgamma, truncf, truncl, trunc, vfscanf, vscanf, vsnprintf, обрабатываются как встроенные функции, за исключением строгого режима ISO C90 (-ansi или -std=c90).
Также имеются встроенные версии функций ISO C99 acosf, acosl, asinf, asinl, atan2f, atan2l, atanf, atanl, ceilf, ceill, cosf, coshf, coshl, cosl, expf, expl, fabsf, fabsl, floorf, floorl, fmodf, fmodl, frexpf, frexpl, ldexpf, ldexpl, log10f, log10l, logf, logl, modfl, modff, powf, powl, sinf, sinhf, sinhl, sinl, sqrtf, sqrtl, tanf, tanhf, tanhl и tanl, которые распознаются в любом режиме, так как ISO C90 резервирует эти имена для цели, для которой ISO C99 их использует. Все эти функции имеют соответствующие версии с префиксом __builtin_.
Также имеются встроенные функции __builtin_fabsfn, __builtin_fabsfnx, __builtin_copysignfn и __builtin_copysignfnx, соответствующие функциям TS 18661-3 fabsfn, fabsfnx, copysignfn и copysignfnx, для поддерживаемых типов _Floatn и _Floatnx.
Также имеются функции расширений GNU clog10, clog10f и clog10l, имена которых зарезервированы ISO C99 для будущего использования. Все эти функции имеют версии с префиксом __builtin_.
Функции ISO C94 iswalnum, iswalpha, iswcntrl, iswdigit, iswgraph, iswlower, iswprint, iswpunct, iswspace, iswupper, iswxdigit, towlower и towupper обрабатываются как встроенные, за исключением строгого режима ISO C90 (-ansi или -std=c90).
Функции ISO C90 abort, abs, acos, asin, atan2, atan, calloc, ceil, cosh, cos, exit, exp, fabs, floor, fmod, fprintf, fputs, free, frexp, fscanf, isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit, tolower, toupper, labs, ldexp, log10, log, malloc, memchr, memcmp, memcpy, memset, modf, pow, printf, putchar, puts, realloc, scanf, sinh, sin, snprintf, sprintf, sqrt, sscanf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, tanh, tan, vfprintf, vprintf и vsprintf распознаются как встроенные функции, если не указан -fno-builtin (или -fno-builtin-function для отдельной функции).
Все эти функции имеют соответствующие версии с префиксом __builtin_.
GCC предоставляет встроенные версии макросов сравнения чисел с плавающей точкой ISO C99, которые не генерируют исключений для неупорядоченных операндов. Они имеют те же имена, что и стандартные макросы ( isgreater, isgreaterequal, isless, islessequal, islessgreater, и isunordered) , с префиксом __builtin_. Мы предполагаем, что реализатор библиотеки сможет просто заменить каждый стандартный макрос на его встроенный аналог. Аналогично, GCC предоставляет встроенные функции fpclassify, isfinite, isinf_sign, isnormal и signbit с префиксом __builtin_. Встроенные функции isinf и isnan представлены как с префиксом __builtin_, так и без него. При использовании опции -ffinite-math-only встроенные функции isinf и isnan всегда возвращают 0.
GCC предоставляет встроенные версии функций округления и обработки исключений чисел с плавающей точкой ISO C99 fegetround, feclearexcept и feraiseexcept. Они могут быть недоступны для всех целевых платформ, и, поскольку они требуют тесного взаимодействия с внутренними значениями libc, они могут быть недоступны для всех целевых libc, но в любом случае они будут корректно перенаправлять вызовы на libc.
Эти встроенные функции представлены как с префиксом __builtin_, так и без него.
- Встроенная функция:
void *__builtin_alloca(size_t size) -
Функция
__builtin_allocaдолжна вызываться в рамках блока. Функция выделяет на стеке вызывающей функции объект размером size байт. Объект выравнивается на границе выравнивания стека по умолчанию для целевой платформы, определяемой макросом__BIGGEST_ALIGNMENT__. Функция__builtin_allocaвозвращает указатель на первый байт выделенного объекта. Жизненный цикл выделенного объекта завершается непосредственно перед возвратом вызывающей функции к своему вызывающему объекту. Это так даже при вызове__builtin_allocaвнутри вложенного блока.Например, следующая функция выделяет восемь объектов по
nбайт каждый на стеке, сохраняя указатель на каждый в последовательных элементах массиваa. Затем она передает массив функцииg, которая может безопасно использовать хранилище, на которое указывает каждый элемент массива.void f (unsigned n) { void *a [8]; for (int i = 0; i != 8; ++i) a [i] = __builtin_alloca (n); g (a, n); // safe }Поскольку функция
__builtin_allocaне проверяет свой аргумент, ответственность за обеспечение того, чтобы аргумент не привел к превышению размера стека, лежит на вызывающей функции. Функция__builtin_allocaпредоставляет возможность выделять на стеке массивы байтов с верхним пределом, который может быть вычислен во время выполнения. В C99 переменные массивы с переменной длиной предлагают аналогичную функциональность в рамках портативного, более удобного и безопасного интерфейса. Их рекомендуется использовать вместо__builtin_alloca, как в программах C99, так и в C++, где GCC предоставляет их в качестве расширения. Подробнее см. Массивы переменной длины.
- Встроенная функция:
void *__builtin_alloca_with_align(size_t size, size_t alignment) -
Функция
__builtin_alloca_with_alignдолжна вызываться в рамках блока. Функция выделяет на стеке вызывающей функции объект размером size байт. Выделенный объект выравнивается на границу, указанную аргументом alignment, единицей измерения которого являются биты (а не байты). Аргумент size должен быть положительным и не превышать предел размера стека. Аргумент alignment должен быть константным целочисленным выражением, которое вычисляется до степени 2, большей или равнойCHAR_BITи меньшей некоторого неопределенного максимума. Вызовы с другими значениями отклоняются с ошибкой, указывающей допустимые границы.Функция возвращает указатель на первый байт выделенного объекта. Жизненный цикл выделенного объекта заканчивается в конце блока, в котором была вызвана функция. Выделенное хранилище освобождается не позднее, чем непосредственно перед тем, как вызывающая функция возвращается к своему вызывающему объекту, но может быть освобождено в конце блока, в котором была вызвана функция.
Например, в следующей функции вызов
gнебезопасен, потому что, еслиoveralignне равно нулю, пространство, выделенное__builtin_alloca_with_align, может быть освобождено в конце инструкцииif, в которой оно было вызвано.void f (unsigned n, bool overalign) { void *p; if (overalign) p = __builtin_alloca_with_align (n, 64 /* bits */); else p = __builtin_alloc (n); g (p, n); // unsafe }Поскольку функция
__builtin_alloca_with_alignне проверяет свой аргумент size, ответственность за обеспечение того, чтобы аргумент не привел к превышению размера стека, лежит на вызывающей функции. Функция__builtin_alloca_with_alignпредоставляет возможность выделять на стеке массивы байтов с произвольным выравниванием, с верхним пределом, который может быть вычислен во время выполнения. В C99 переменные массивы с переменной длиной предлагают аналогичную функциональность в рамках портативного, более удобного и безопасного интерфейса. Их рекомендуется использовать вместо__builtin_alloca_with_align, как в программах C99, так и в C++, где GCC предоставляет их в качестве расширения. Подробнее см. Массивы переменной длины.
- Встроенная функция:
void *__builtin_alloca_with_align_and_max(size_t size, size_t alignment, size_t max_size) -
Аналогично
__builtin_alloca_with_align, но принимает дополнительный аргумент, указывающий верхнюю границу для size в случае, если его значение не может быть вычислено на этапе компиляции, для использования с -fstack-usage, -Wstack-usage и -Walloca-larger-than. max_size должно быть константным целочисленным выражением. Оно не влияет на генерацию кода и не проверяется на совместимость со значением size.
-
Встроенная функция:
bool__builtin_has_attribute(type-or-expression, attribute) -
Функция
__builtin_has_attributeвозвращает целочисленное константное выражение, равноеtrue, если символ или тип, на который ссылается аргумент type-or-expression, объявлен с атрибутом, указанным во втором аргументе. Для аргумента type-or-expression, не ссылающегося на символ, поскольку атрибуты не применяются к выражениям, встроенная функция рассматривает тип аргумента. Ни один из аргументов не вычисляется. Аргумент type-or-expression подчиняется тем же ограничениям, что и аргумент функцииtypeof(см. Ссылка на тип сtypeof). Аргумент attribute — это имя атрибута, за которым необязательно следует список аргументов, разделенных запятыми, заключённых в скобки. Признаются оба формата имён атрибутов — с и без двойных ведущих и завершающих подчёркиваний. Подробнее см. Синтаксис атрибутов. Если для атрибута, ожидающего один или несколько аргументов, не указано ни одного аргумента, функция возвращаетtrue, если type-or-expression объявлен с этим атрибутом независимо от значений аргументов атрибута. Предоставленные аргументы для атрибута, ожидающего некоторые, проверяются и сопоставляются с предоставленным количеством. Функция возвращаетtrue, если все предоставленные аргументы совпадают. Например, первый вызов функции ниже возвращаетtrue, потому чтоxобъявлен с атрибутомaligned, но второй вызов возвращаетfalse, потому чтоxобъявлен сaligned (8), а не сaligned (4).__attribute__ ((aligned (8))) int x; _Static_assert (__builtin_has_attribute (x, aligned), "aligned"); _Static_assert (!__builtin_has_attribute (x, aligned (4)), "aligned (4)");
Из-за ограничения функция
__builtin_has_attributeвозвращаетfalseдля атрибутаmode, даже если тип или переменная, на которую ссылается аргумент type-or-expression, были объявлены с ним. Функция также не поддерживается с метками и в C с перечислениями.Обратите внимание, что в отличие от препроцессорного оператора
__has_attribute, подходящего для использования в#ifпрепроцессорных директивах,__builtin_has_attributeявляется встроенной функцией, которая не распознаётся в таких контекстах.
-
Встроенная функция:
type__builtin_speculation_safe_value(type val, type failval) -
Эта встроенная функция может использоваться для снижения рисков небезопасного спекулятивного выполнения. type может быть любым целочисленным типом или любым указательным типом.
- Если процессор не выполняет код спекулятивно, то возвращается val.
- Если процессор выполняет код спекулятивно, то либо:
- Функция может приостановить выполнение до тех пор, пока не станет известно, что код больше не выполняется спекулятивно (в этом случае можно вернуть val, как выше); или
- Функция может использовать зависящее от целевой платформы состояние отслеживания спекуляций, чтобы вернуть failval, когда станет известно, что спекулятивное выполнение ошибочно предсказало операцию условного перехода.
Второй аргумент failval необязателен и по умолчанию равен нулю, если опущен.
GCC определяет препроцессорную макрос
__HAVE_BUILTIN_SPECULATION_SAFE_VALUEдля платформ, обновлённых для поддержки этой встроенной функции.Встроенная функция может быть использована в случаях, когда переменная, кажется, используется безопасно, но процессор из-за спекулятивного выполнения временно игнорирует проверки границ. Например, рассмотрим следующую функцию:
int array[500]; int f (unsigned untrusted_index) { if (untrusted_index < 500) return array[untrusted_index]; return 0; }Если функция вызывается многократно со значением
untrusted_indexменьше предела 500, то предсказатель ветвлений научится тому, что блок кода, возвращающий значение, хранящееся вarray, будет выполняться. Если функция впоследствии вызывается со значением вне диапазона, она по-прежнему будет пытаться выполнить этот блок кода первой, пока процессор не определит, что прогноз был неверным (процессор размотает все неверные операции в этот момент). Однако, в зависимости от того, как используется результат функции, возможно оставить следы в кэше, которые могут раскрыть, что было хранилось в позиции вне границ. Встроенная функция может обеспечить некоторую защиту от утечки данных таким образом, изменив код на:int array[500]; int f (unsigned untrusted_index) { if (untrusted_index < 500) return array[__builtin_speculation_safe_value (untrusted_index)]; return 0; }Встроенная функция либо заставит выполнение приостановиться до полного разрешения условного перехода, либо позволит спекулятивному выполнению продолжить, но используя 0 вместо
untrusted_value, если это превысит предел.Если доступ к любой ячейке памяти потенциально небезопасен при неверном спекулятивном выполнении, то код можно переписать как
int array[500]; int f (unsigned untrusted_index) { if (untrusted_index < 500) return *__builtin_speculation_safe_value (&array[untrusted_index], NULL); return 0; }что приведёт к использованию указателя
NULLдля небезопасного случая.
-
Встроенная функция:
int__builtin_types_compatible_p(type1, type2) -
Вы можете использовать встроенную функцию
__builtin_types_compatible_pдля определения того, являются ли два типа одинаковыми.Эта встроенная функция возвращает 1, если неквалифицированные версии типов type1 и type2 (которые являются типами, а не выражениями) совместимы, и 0 в противном случае. Результат этой встроенной функции может использоваться в целочисленных константных выражениях.
Эта встроенная функция игнорирует квалификаторы верхнего уровня (например,
const,volatile). Например,intэквивалентноconst int.Тип
int[]иint[5]совместимы. С другой стороны,intиchar *не совместимы, даже если размер их типов на конкретной архитектуре одинаков. Также учитывается количество косвенных указаний при определении сходства. Следовательно,short *не аналогиченshort **. Кроме того, два типа, определённые с помощью typedef, считаются совместимыми, если их базовые типы совместимы.Тип
enumне считается совместимым с типомenumдаже если оба совместимы с одним и тем же целочисленным типом; именно это определяет стандарт C. Например,enum {foo, bar}не подобенenum {hot, dog}.Обычно эту функцию используют в коде, выполнение которого зависит от типов аргументов. Например:
#define foo(x) \ ({ \ typeof (x) tmp = (x); \ if (__builtin_types_compatible_p (typeof (x), long double)) \ tmp = foo_long_double (tmp); \ else if (__builtin_types_compatible_p (typeof (x), double)) \ tmp = foo_double (tmp); \ else if (__builtin_types_compatible_p (typeof (x), float)) \ tmp = foo_float (tmp); \ else \ abort (); \ tmp; \ })Примечание: Данный конструкт доступен только для C.
-
Встроенная функция:
type__builtin_call_with_static_chain(call_exp, pointer_exp) -
Выражение call_exp должно быть вызовом функции, а выражение pointer_exp должно быть указателем. pointer_exp передаётся в вызов функции в местоположение статической цепи целевой платформы. Результатом встроенной функции является результат вызова функции.
Примечание: Эта встроенная функция доступна только для C. Она может использоваться для вызова лямбда-функций Go из C.
-
Встроенная функция:
type__builtin_choose_expr(const_exp, exp1, exp2) -
Вы можете использовать встроенную функцию
__builtin_choose_exprдля оценки кода в зависимости от значения целочисленного константного выражения const_exp. Эта встроенная функция возвращает exp1, если const_exp отлично от нуля. В противном случае возвращается exp2.Эта встроенная функция аналогична оператору ‘? :’ в C, за исключением того, что тип возвращаемого выражения не изменяется правилами повышения. Кроме того, встроенная функция не вычисляет невыбранное выражение. Например, если const_exp равно
true, exp2 не вычисляется, даже если оно имеет побочные эффекты.Эта встроенная функция может возвращать lvalue, если выбранный аргумент является lvalue.
Если возвращается exp1, тип возврата совпадает с типом exp1. Аналогично, если возвращается exp2, его тип возврата совпадает с типом exp2.
Пример:
#define foo(x) \ __builtin_choose_expr ( \ __builtin_types_compatible_p (typeof (x), double), \ foo_double (x), \ __builtin_choose_expr ( \ __builtin_types_compatible_p (typeof (x), float), \ foo_float (x), \ /* The void expression results in a compile-time error \ when assigning the result to something. */ \ (void)0))Примечание: Этот конструкт доступен только для C. Кроме того, неиспользуемое выражение (exp1 или exp2 в зависимости от значения const_exp) может всё ещё генерировать синтаксические ошибки. Это может измениться в будущих версиях.
-
Встроенная функция:
type__builtin_tgmath(functions, arguments) -
Встроенная функция
__builtin_tgmath, доступная только для C и Objective-C, вызывает функцию, определяемую по правилам<tgmath.h>макросов. Она предназначена для использования в реализациях этих заголовков, чтобы расширения макросов из этого заголовка расширяли каждый из своих аргументов только один раз, чтобы избежать проблем, когда вызовы таких макросов вложены внутри аргументов других вызовов таких макросов; кроме того, это приводит к лучшей диагностике некорректных вызовов<tgmath.h>макросов, чем реализации, использующие другие возможности языка GNU C. Например,powтип-обобщённый макрос может быть определён как:#define pow(a, b) __builtin_tgmath (powf, pow, powl, \ cpowf, cpow, cpowl, a, b)Аргументы
__builtin_tgmath— это по меньшей мере два указателя на функции, за которыми следуют аргументы тип-обобщённого макроса (которые будут переданы в качестве аргументов выбранной функции). Все указатели на функции должны быть указателями на прототипированные функции, ни одна из которых не может иметь переменное число аргументов, и все они должны иметь одинаковое количество параметров; количество параметров первой функции определяет, сколько аргументов__builtin_tgmathинтерпретируются как указатели на функции, а сколько — как аргументы вызываемой функции.Типы указанных функций должны быть все различными, но связаны между собой так же, как набор функций, между которыми можно выбирать с помощью макроса в
<tgmath.h>. Это означает, что функции параметризованы типом с плавающей точкой t, отличным для каждой такой функции. Типы возвращаемых значений функций могут быть все одного типа, или они могут быть типом t для каждой функции, или они могут быть реальным типом, соответствующим t для каждой функции (если некоторые из типов t — комплексные). Аналогично, для каждой позиции параметра тип параметра в этой позиции может быть всегда одним и тем же типом, или может быть t для каждой функции (этот случай должен применяться по крайней мере для одной позиции параметра), или может быть реальным типом, соответствующим t для каждой функции.Используются стандартные правила для
<tgmath.h>макросов, чтобы найти общий тип u из типов аргументов для параметров, типы которых меняются между функциями; комплексные целочисленные типы (расширение GNU) обрабатываются как комплексный тип, соответствующий реально-плавающему типу, который был бы выбран для соответствующего целочисленного типа. Если типы возвращаемых значений функций меняются или являются все одним целым типом, вызывается функция, для которой t равно u, и это ошибка, если такой функции нет. Если типы возвращаемых значений функций — все один и тот же тип с плавающей точкой, тип-обобщённый макрос считается одним из тех, что из TS 18661, которые округляют результат до более узкого типа; если существует функция, для которой t равно u, она вызывается, а в противном случае — первая функция, если таковая есть, для которой t имеет по меньшей мере диапазон и точность u, вызывается, и это ошибка, если такой функции нет.
-
Встроенная функция:
int__builtin_constant_p(exp) -
Вы можете использовать встроенную функцию
__builtin_constant_p, чтобы определить, известно ли значение как константа во время компиляции, и поэтому GCC может выполнить условное подстановку констант в выражения, включающие это значение. Аргументом функции является значение, которое нужно проверить. Функция возвращает целое число 1, если аргумент известен как константа во время компиляции, и 0, если он не известен как константа во время компиляции. Возврат 0 не указывает, что значение не является константой, а только то, что GCC не может доказать, что это константа с указанным значением опции -O.Обычно вы используете эту функцию в встроенном приложении, где память — критический ресурс. Если у вас есть какое-то сложное вычисление, вы можете захотеть, чтобы оно было сложено, если оно включает константы, но вам нужно вызвать функцию, если это не так. Например:
#define Scale_Value(X) \ (__builtin_constant_p (X) \ ? ((X) * SCALE + OFFSET) : Scale (X))
Вы можете использовать эту встроенную функцию как в макросе, так и во встроенной функции. Однако, если вы используете её во встроенной функции и передаёте аргумент функции в качестве аргумента встроенной функции, GCC никогда не возвращает 1 при вызове встроенной функции со строковой константой или составным литералом (см. Составные литералы) и не возвращает 1 при передаче числовой константы в встроенную функцию, если вы не укажете опцию -O.
Вы также можете использовать
__builtin_constant_pв инициализаторах для статических данных. Например, вы можете написатьstatic const int table[] = { __builtin_constant_p (EXPRESSION) ? (EXPRESSION) : -1, /* … */ };Это допустимый инициализатор, даже если EXPRESSION не является выражением константы, включая случай, когда
__builtin_constant_pвозвращает 1, потому что EXPRESSION можно сложить в константу, но EXPRESSION содержит операнды, которые в противном случае не допускаются в статическом инициализаторе (например,0 && foo ()). GCC должен быть более консервативным при оценке встроенной функции в этом случае, потому что у него нет возможности выполнить оптимизацию.
-
Встроенная функция:
bool__builtin_is_constant_evaluated(void) -
Функция
__builtin_is_constant_evaluatedдоступна только в C++. Встроенная функция предназначена для использования реализациямиstd::is_constant_evaluatedфункции C++. Программы должны использовать последнюю функцию вместо прямого вызова встроенной.Основной случай использования встроенной функции — определить, вызывается ли
constexprфункция вconstexprконтексте. Вызов функции оценивается как ядро выражения константы со значениемtrue, если и только если он встречается внутри оценки выражения или преобразования, которые явно оцениваются как константы, как определено в стандарте C++. К явным контекстам оценки констант относятся выражения-константы, условияconstexpr ifоператоров, выражения ограничений и инициализаторы переменных, используемых в выражениях констант. Более подробную информацию см. в последней редакции стандарта C++.
-
Встроенная функция:
void__builtin_clear_padding(ptr) -
Встроенная функция
__builtin_clear_paddingочищает биты заполнения внутри представления объекта, на который указывает ptr, который должен быть указателем. Представление значения объекта не изменяется. Предполагается, что тип объекта — тип, на который указывает указатель. Внутри объединения очищаются только биты, которые являются битами заполнения для всех членов объединения.Эта встроенная функция полезна, если биты заполнения объекта могут иметь неопределённые значения, и представление объекта нужно сравнивать по битам с каким-либо другим объектом, например, для атомарных операций.
Для C++, аргумент ptr должен быть указателем на тип, допускающий тривиальную копирование, если аргумент — адрес переменной или параметра, иначе неизвестно, не является ли тип просто базовым классом, биты заполнения которого повторно используются или выстроены иначе в производном классе.
-
Встроенная функция:
type__builtin_bit_cast(type, arg) -
Функция
__builtin_bit_castдоступна только в C++. Встроенная функция предназначена для использования реализациямиstd::bit_castшаблонной функции C++. Программы должны использовать последнюю функцию вместо прямого вызова встроенной.Эта встроенная функция позволяет переинтерпретировать биты аргумента arg так, как если бы он имел тип type. type и тип аргумента arg должны быть типами, допускающими тривиальную копирование, с одинаковым размером. При явной оценке констант она выполняет дополнительную диагностику, необходимую для
std::bit_cast, и возвращает выражение константы, если arg является выражением константы. Более подробную информацию см. в последней редакции стандарта C++.
-
Встроенная функция:
long__builtin_expect(long exp, long c) -
Вы можете использовать
__builtin_expectдля предоставления компилятору информации о прогнозировании ветвлений. В общем случае вы должны отдавать предпочтение фактической обратной связи профиля для этого (-fprofile-arcs), поскольку программисты печально известны тем, что плохо предсказывают реальное поведение своих программ. Однако существуют приложения, в которых эти данные трудно собрать.Возвращаемое значение — значение exp, которое должно быть целочисленным выражением. Семантика встроенной функции заключается в том, что ожидается, что exp == c. Например:
if (__builtin_expect (x, 0)) foo ();
указывает, что мы не ожидаем вызова
foo, так как мы ожидаем, чтоxбудет равно нулю. Поскольку вы ограничены целочисленными выражениями для exp, вы должны использовать конструкции, такие какif (__builtin_expect (ptr != NULL, 1)) foo (*ptr);
при тестировании указателей или значений с плавающей точкой.
Для целей оптимизации прогнозирования ветвлений вероятность того, что выражение
__builtin_expectравноtrue, контролируется параметромbuiltin-expect-probabilityGCC, который по умолчанию равен 90%.Вы также можете использовать
__builtin_expect_with_probabilityдля явного назначения значения вероятности отдельным выражениям. Если встроенная функция используется в цикле, указанная вероятность повлияет на ожидаемое число итераций, выполняемых оптимизациями цикла.
-
Встроенная функция:
long__builtin_expect_with_probability -
(long exp, long c, double probability)
Эта функция имеет ту же семантику, что и
__builtin_expect, но вызывающая функция предоставляет ожидаемую вероятность того, что exp == c. Последний аргумент, probability, — значение с плавающей запятой в диапазоне от 0,0 до 1,0 включительно. Аргумент probability должен быть константным выражением с плавающей запятой.
-
Встроенная функция:
void__builtin_trap(void) Эта функция вызывает ненормальное завершение программы. GCC реализует эту функцию с помощью зависящего от платформы механизма (например, преднамеренного выполнения недопустимой инструкции) или вызова
abort. Использованный механизм может изменяться в разных релизах, поэтому вы не должны полагаться на какую-либо конкретную реализацию.
-
Встроенная функция:
void__builtin_unreachable(void) -
Если поток управления достигает точки
__builtin_unreachable, поведение программы не определено. Это полезно в ситуациях, когда компилятор не может определить недостижимость кода.Один из таких случаев — сразу после оператора
asm, который либо никогда не завершается, либо передаёт управление в другое место и никогда не возвращается. В этом примере, без__builtin_unreachable, GCC выдает предупреждение о том, что управление достигает конца функции, не возвращающей значение. Также генерируется код для возврата послеasm.int f (int c, int v) { if (c) { return v; } else { asm("jmp error_handler"); __builtin_unreachable (); } }Поскольку оператор
asmбезусловно передаёт управление за пределы функции, управление никогда не достигает конца тела функции.__builtin_unreachableфактически недостижима и сообщает об этом компилятору.Другое применение
__builtin_unreachable— следование за вызовом функции, которая никогда не возвращается, но не объявлена__attribute__((noreturn)), как в этом примере:void function_that_never_returns (void); int g (int c) { if (c) { return 1; } else { function_that_never_returns (); __builtin_unreachable (); } }
-
Встроенная функция:
type__builtin_assoc_barrier(type expr) -
Эта встроенная функция препятствует повторной ассоциации выражения с плавающей точкой expr с выражениями, использующими возвращаемое значение встроенной функции. Само выражение expr может быть переупорядочено, и всё выражение expr может быть переупорядочено с операндами после барьера. Барьер актуален только когда
-fassociative-mathактивен, так как в противном случае арифметика с плавающей точкой не рассматривается как ассоциативная.float x0 = a + b - b; float x1 = __builtin_assoc_barrier(a + b) - b;
означает, что с
-fassociative-math,x0может быть оптимизирован доx0 = a, ноx1не может.
-
Встроенная функция:
void *__builtin_assume_aligned(const void *exp, size_t align, ...) -
Эта функция возвращает свой первый аргумент и позволяет компилятору предположить, что возвращаемый указатель выровнен по крайней мере на align байт. У этой встроенной функции может быть два или три аргумента; если три, третий аргумент должен иметь целочисленный тип, и если он не равен нулю, это означает смещение невыравнивания. Например:
void *x = __builtin_assume_aligned (arg, 16);
означает, что компилятор может предположить, что
x, установленный вarg, выровнен по крайней мере на 16 байт, в то время как:void *x = __builtin_assume_aligned (arg, 32, 8);
означает, что компилятор может предположить для
x, установленного вarg, что(char *) x - 8выровнен по крайней мере на 32 байта.
-
Встроенная функция:
int__builtin_LINE() Эта функция эквивалентна препроцессорной макрокоманде
__LINE__и возвращает константное целочисленное выражение, которое оценивается в строку вызова встроенной функции. При использовании в качестве аргумента по умолчанию C++ для функции F она возвращает номер строки вызова F.
-
Встроенная функция:
const char *__builtin_FUNCTION() Эта функция эквивалентна символу
__FUNCTION__и возвращает константный адрес, указывающий на имя функции, из которой был вызван встроенный элемент, или пустую строку, если вызов не находится в области видимости функции. При использовании в качестве аргумента по умолчанию C++ для функции F она возвращает имя вызывающей F функции или пустую строку, если вызов не находится в области видимости функции.
-
Встроенная функция:
const char *__builtin_FILE() -
Эта функция эквивалентна препроцессорной макрокоманде
__FILE__и возвращает константный адрес, указывающий на имя файла, содержащего вызов встроенного элемента, или пустую строку, если вызов не находится в области видимости функции. При использовании в качестве аргумента по умолчанию C++ для функции F она возвращает имя файла вызова F или пустую строку, если вызов не находится в области видимости функции.Например, в следующем примере каждый вызов функции
fooвыведет строку, похожую на"file.c:123: foo: message", с именем файла и номером строки вызоваprintf, именем функцииfoo, за которым следует словоmessage.const char* function (const char *func = __builtin_FUNCTION ()) { return func; } void foo (void) { printf ("%s:%i: %s: message\n", file (), line (), function ()); }
-
Встроенная функция:
void__builtin___clear_cache(void *begin, void *end) -
Эта функция используется для сброса кэша инструкций процессора для области памяти между begin (включительно) и end (исключительно). Некоторые платформы требуют сброса кэша инструкций после изменения памяти, содержащей код, для получения детерминированного поведения.
Если целевая платформа не требует сброса кэша инструкций,
__builtin___clear_cacheне имеет эффекта. В противном случае либо генерируются инструкции для сброса кэша инструкций, либо делается вызов функции__clear_cacheв libgcc.
-
Встроенная функция:
void__builtin_prefetch(const void *addr, ...) -
Эта функция используется для минимизации задержки промаха кэша, перемещая данные в кэш перед доступом. Вы можете вставлять вызовы
__builtin_prefetchв код, для которого известны адреса данных в памяти, которые вероятно будут скоро обработаны. Если платформа их поддерживает, генерируются инструкции предварительной выборки данных. Если предварительная выборка выполняется достаточно рано перед доступом, то данные будут в кэше к моменту доступа.Значение addr — адрес памяти для предварительной выборки. Есть два необязательных аргумента, rw и locality. Значение rw — константа времени компиляции 1 или 0; 1 означает, что предварительная выборка готовит запись в адрес памяти, а 0 (значение по умолчанию) означает, что предварительная выборка готовит чтение. Значение locality должно быть константой времени компиляции целого числа от нуля до трёх. Значение 0 означает, что данные не обладают временной локальностью, поэтому их не нужно оставлять в кэше после доступа. Значение 3 означает, что данные обладают высокой степенью временной локальности и должны оставаться во всех уровнях кэша, насколько возможно. Значения 1 и 2 соответственно означают низкую или среднюю степень временной локальности. Значение по умолчанию — 3.
for (i = 0; i < n; i++) { a[i] = a[i] + b[i]; __builtin_prefetch (&a[i+j], 1, 1); __builtin_prefetch (&b[i+j], 0, 1); /* … */ }Предварительная выборка данных не генерирует ошибки, если addr недействителен, но само выражение адреса должно быть действительным. Например, предварительная выборка
p->nextне вызывает ошибки, еслиp->nextне является действительным адресом, но оценка вызывает ошибку, еслиpне является действительным адресом.Если платформа не поддерживает предварительную выборку данных, выражение адреса оценивается, если оно содержит побочные эффекты, но другой код не генерируется, и GCC не выдает предупреждение.
-
Встроенная функция:
size_t__builtin_object_size(const void * ptr, int type) Возвращает оценочный размер объекта, на который указывает ptr. Подробное описание функции см. в разделе Проверка размера объектов.
-
Встроенная функция:
size_t__builtin_dynamic_object_size(const void * ptr, int type) Аналогично
__builtin_object_size, за исключением того, что возвращаемое значение не должно быть константой. Подробное описание функции см. в разделе Проверка размера объектов.
-
Встроенная функция:
double__builtin_huge_val(void) Возвращает положительную бесконечность, если поддерживается форматом с плавающей точкой, иначе
DBL_MAX. Эта функция подходит для реализации макроса ISO CHUGE_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 C99INFINITY.
-
Встроенная функция:
long double__builtin_infl(void) Аналогично
__builtin_inf, за исключением того, что тип возвращаемого значенияlong double.
-
Встроенная функция:
_Floatn__builtin_inffn(void) Аналогично
__builtin_inf, за исключением того, что тип возвращаемого значения_Floatn.
-
Встроенная функция:
_Floatn__builtin_inffnx(void) Аналогично
__builtin_inf, за исключением того, что тип возвращаемого значения_Floatnx.
-
Встроенная функция:
int__builtin_isinf_sign(...) Аналогично
isinf, за исключением того, что возвращаемое значение равно -1 для аргумента-Infи 1 для аргумента+Inf. Обратите внимание, что хотя список параметров представляет собой многоточие, эта функция принимает только один аргумент с плавающей точкой. GCC обрабатывает этот параметр как универсальный по типу, что означает, что он не выполняет неявное преобразование типа float в double.
-
Встроенная функция:
double__builtin_nan(const char *str) -
Это реализация функции ISO C99
nan.Поскольку ISO C99 определяет эту функцию в терминах
strtod, которые мы не реализуем, необходимо описание разбора. Строка разбирается так же, как иstrtol; то есть, основание распознается по префиксам «0» или «0x». Разобранное число помещается в мантиссу таким образом, что наименее значимый бит числа находится в наименее значимом бите мантиссы. Число усекается, чтобы соответствовать предоставленному полю мантиссы. Мантисса принудительно устанавливается в значение «тихое NaN».Эта функция, если ей передается строковая константа, которая была бы полностью обработана
strtol, вычисляется достаточно рано, чтобы считаться константой времени компиляции.
-
Встроенная функция:
_Decimal32__builtin_nand32(const char *str) Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значения_Decimal32.
-
Встроенная функция:
_Decimal64__builtin_nand64(const char *str) Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значения_Decimal64.
-
Встроенная функция:
_Decimal128__builtin_nand128(const char *str) Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значения_Decimal128.
-
Встроенная функция:
float__builtin_nanf(const char *str) Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значенияfloat.
-
Встроенная функция:
long double__builtin_nanl(const char *str) Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значенияlong double.
-
Встроенная функция:
_Floatn__builtin_nanfn(const char *str) Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значения_Floatn.
-
Встроенная функция:
_Floatnx__builtin_nanfnx(const char *str) Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значения_Floatnx.
-
Встроенная функция:
double__builtin_nans(const char *str) Аналогично
__builtin_nan, за исключением того, что мантисса принудительно устанавливается в значение «сигнальное NaN». Функцияnansпредложена WG14 N965.
-
Встроенная функция:
_Decimal32__builtin_nansd32(const char *str) Аналогично
__builtin_nans, за исключением того, что тип возвращаемого значения_Decimal32.
-
Встроенная функция:
_Decimal64__builtin_nansd64(const char *str) Аналогично
__builtin_nans, за исключением того, что возвращаемый тип —_Decimal64.
-
Встроенная функция:
_Decimal128__builtin_nansd128(const char *str) Аналогично
__builtin_nans, за исключением того, что возвращаемый тип —_Decimal128.
-
Встроенная функция:
float__builtin_nansf(const char *str) Аналогично
__builtin_nans, за исключением того, что возвращаемый тип —float.
-
Встроенная функция:
long double__builtin_nansl(const char *str) Аналогично
__builtin_nans, за исключением того, что возвращаемый тип —long double.
-
Встроенная функция:
_Floatn__builtin_nansfn(const char *str) Аналогично
__builtin_nans, за исключением того, что возвращаемый тип —_Floatn.
-
Встроенная функция:
_Floatnx__builtin_nansfnx(const char *str) Аналогично
__builtin_nans, за исключением того, что возвращаемый тип —_Floatnx.
-
Встроенная функция:
int__builtin_issignaling(...) Возвращает ненулевое значение, если аргумент является сигнализирующим NaN, и ноль в противном случае. Обратите внимание, что хотя список параметров является многоточием, эта функция принимает только один аргумент с плавающей точкой. GCC обрабатывает этот параметр как универсальный по типу, что означает, что он не выполняет стандартное повышение типа от float до double. Эта встроенная функция может работать даже без параметра
-fsignaling-nans, хотя, если сигнализирующий NaN вычисляется, сохраняется или передается как аргумент какой-либо функции, отличной от этой встроенной в текущем трансляционном блоке, безопаснее использовать-fsignaling-nans. С параметром-ffinite-math-onlyэта встроенная функция всегда будет возвращать 0.
-
Встроенная функция:
int__builtin_ffs(int x) Возвращает единицу плюс индекс наименее значимого 1-бита x, или, если x равно нулю, возвращает ноль.
-
Встроенная функция:
int__builtin_clz(unsigned int x) Возвращает количество старших 0-битов в x, начиная с наиболее значимого бита. Если x равно 0, результат не определен.
-
Встроенная функция:
int__builtin_ctz(unsigned int x) Возвращает количество младших 0-битов в x, начиная с наименее значимого бита. Если x равно 0, результат не определен.
-
Встроенная функция:
int__builtin_clrsb(int x) Возвращает количество старших избыточных битов знака в x, т.е. количество битов после наиболее значимого бита, которые идентичны ему. Нет никаких особых случаев для 0 или других значений.
-
Встроенная функция:
int__builtin_popcount(unsigned int x) Возвращает количество 1-битов в x.
-
Встроенная функция:
int__builtin_parity(unsigned int x) Возвращает четность x, т.е. количество 1-битов в x по модулю 2.
-
Встроенная функция:
int__builtin_ffsl(long) Аналогично
__builtin_ffs, за исключением того, что тип аргумента —long.
-
Встроенная функция:
int__builtin_clzl(unsigned long) Аналогично
__builtin_clz, за исключением того, что тип аргумента —unsigned long.
-
Встроенная функция:
int__builtin_ctzl(unsigned long) Аналогично
__builtin_ctz, за исключением того, что тип аргумента —unsigned long.
-
Встроенная функция:
int__builtin_clrsbl(long) Аналогично
__builtin_clrsb, за исключением того, что тип аргумента —long.
-
Встроенная функция:
int__builtin_popcountl(unsigned long) Аналогично
__builtin_popcount, за исключением того, что тип аргумента —unsigned long.
-
Встроенная функция:
int__builtin_parityl(unsigned long) Аналогично
__builtin_parity, за исключением того, что тип аргумента —unsigned long.
-
Встроенная функция:
int__builtin_ffsll(long long) Аналогично
__builtin_ffs, за исключением того, что тип аргумента —long long.
-
Встроенная функция:
int__builtin_clzll(unsigned long long) Аналогично
__builtin_clz, за исключением того, что тип аргумента —unsigned long long.
-
Встроенная функция:
int__builtin_ctzll(unsigned long long) Аналогично
__builtin_ctz, за исключением того, что тип аргумента —unsigned long long.
-
Встроенная функция:
int__builtin_clrsbll(long long) Аналогично
__builtin_clrsb, за исключением того, что тип аргумента —long long.
-
Встроенная функция:
int__builtin_popcountll(unsigned long long) Аналогично
__builtin_popcount, за исключением того, что тип аргумента —unsigned long long.
-
Встроенная функция:
int__builtin_parityll(unsigned long long) Аналогично
__builtin_parity, за исключением того, что тип аргумента —unsigned long long.
-
Встроенная функция:
double__builtin_powi(double, int) -
Встроенная функция:
float__builtin_powif(float, int) -
Встроенная функция:
long double__builtin_powil(long double, int) Возвращает первый аргумент, возведенный в степень второго. В отличие от функции
powникаких гарантий относительно точности и округления не дается.
-
Встроенная функция:
uint16_t__builtin_bswap16(uint16_t x) Возвращает x с изменённым порядком байтов; например,
0xaabbстановится0xbbaa. Байтом здесь всегда является ровно 8 бит.
-
Встроенная функция:
uint32_t__builtin_bswap32(uint32_t x) Аналогично
__builtin_bswap16, за исключением того, что аргумент и возвращаемое значение являются 32-битными.
-
Встроенная функция:
uint64_t__builtin_bswap64(uint64_t x) Аналогично
__builtin_bswap32, за исключением того, что аргумент и возвращаемое значение являются 64-битными.
-
Встроенная функция:
uint128_t__builtin_bswap128(uint128_t x) Аналогично
__builtin_bswap64, за исключением того, что аргумент и возвращаемое значение являются 128-битными. Поддерживается только на целевых платформах, где поддерживаются 128-битные типы.
-
Встроенная функция:
Pmode__builtin_extend_pointer(void * x) На целевых платформах, где размер видимого пользователю указателя меньше размера фактического адреса аппаратного обеспечения, эта функция возвращает расширенный пользовательский указатель. Целевые платформы, где это справедливо, включают режим ILP32 на x86_64 или Aarch64. Эта функция в основном полезна при написании кода встроенного языка ассемблера.
-
Встроенная функция:
int__builtin_goacc_parlevel_id(int x) Возвращает идентификатор openacc gang, worker или vector в зависимости от того, является ли x 0, 1 или 2.
-
Встроенная функция:
int__builtin_goacc_parlevel_size(int x) Возвращает размер openacc gang, worker или vector в зависимости от того, является ли x 0, 1 или 2.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gcc/Other-Builtins.html