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, roudnevenl, 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).
Существуют также встроенные версии функций 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, 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_. Мы предполагаем, что разработчик библиотеки сможет просто #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(см. Ссылка на тип с помощью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 **. Кроме того, два типа, которые являются typedefed, считаются совместимыми, если их базовые типы совместимы.Тип
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для оценки кода в зависимости от значения выражения константы. Эта встроенная функция возвращает 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) обрабатываются как_Complex doubleдля этой цели (или_Complex _Float64, если все типы возвращаемых значений функции одинаковы_Floatnили_Floatnxтипа). Если типы возвращаемых значений функции различаются или все являются одним и тем же целочисленным типом, вызывается функция, для которой t равно u, и это ошибка, если такой функции нет. Если типы возвращаемых значений функции все одного типа с плавающей запятой, универсальный по типу макрос считается одним из тех, что есть в TS 18661, которые округляют результат до более узкого типа; если есть функция, для которой t равно u, она вызывается, а в противном случае вызывается первая функция, если таковая имеется, для которой t имеет как минимум диапазон и точность u, и это ошибка, если такой функции нет.
-
Встроенная функция:
type__builtin_complex(real, imag)¶ -
Встроенная функция
__builtin_complexпредоставляется для использования при реализации макросов ISO C11CMPLXF,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_evaluatedC++. Программы должны использовать последнюю функцию, а не вызывать встроенную функцию напрямую.Основной случай использования встроенной функции — определить, вызывается ли функция
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, контролируется параметром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_unreachableGCC выдает предупреждение о том, что управление достигает конца функции, не возвращающей значение. Он также генерирует код для возврата после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 — это константа времени компиляции, равная единице или нулю; единица означает, что предварительная выборка готовится к записи по адресу памяти, а ноль (значение по умолчанию) означает, что предварительная выборка готовится к чтению. Значение locality должно быть целым числом-константой времени компиляции от нуля до трех. Значение нуль означает, что данные не имеют временной локальности, поэтому их не нужно оставлять в кэше после доступа. Значение три означает, что данные имеют высокую степень временной локальности и должны оставаться во всех возможных уровнях кэша. Значения один и два означают соответственно низкую или умеренную степень временной локальности. Значение по умолчанию — три.
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 не выдает предупреждение.
-
Встроенная функция: __builtin_object_size
(const void * ptr, int type)¶ Возвращает размер объекта, на который указывает ptr. См. Встроенные функции проверки размера объекта для подробного описания функции.
-
Встроенная функция:
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, ...)¶ Эта встроенная функция реализует функциональность fpclassify C99. Первые пять аргументов типа 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.
-
Встроенная функция:
float__builtin_nansf(const char *str)¶ Аналогично
__builtin_nans, за исключением того, что тип возвращаемого значения —float.
-
Встроенная функция:
long double__builtin_nansl(const char *str)¶ Аналогично
__builtin_nans, за исключением того, что тип возвращаемого значения —long double.
-
Встроенная функция:
_Floatn__builtin_nansfn(const char *str)¶ Аналогично
__builtin_nans, за исключением того, что тип возвращаемого значения —_Floatn.
-
Встроенная функция:
_Floatnx__builtin_nansfnx(const char *str)¶ Аналогично
__builtin_nans, за исключением того, что тип возвращаемого значения —_Floatnx.
-
Встроенная функция:
int__builtin_ffs(int x)¶ Возвращает единицу плюс индекс наименее значимого 1-бита x, или если x равно нулю, возвращает ноль.
-
Встроенная функция:
int__builtin_clz(unsigned int x)¶ Возвращает количество ведущих 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)¶ Возвращает первый аргумент, возведенный в степень второго. В отличие от функции
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.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-10.5.0/gcc/Other-Builtins.html