6.56 Другие встроенные функции, предоставляемые GCC
GCC предоставляет большое количество встроенных функций помимо упомянутых выше. Некоторые из них предназначены для внутреннего использования при обработке исключений или списков аргументов переменной длины и не документированы здесь, так как они могут время от времени изменяться; мы не рекомендуем их общее использование.
Остальные функции предоставляются для оптимизации.
GCC включает встроенные версии многих функций стандартной библиотеки C. Версии, начинающиеся с __builtin_ , всегда интерпретируются так же, как функция библиотеки C, даже если вы укажете опцию -fno-builtin. (см. Опции диалекта C) Многие из этих функций оптимизируются только в определенных случаях; если они не оптимизируются в конкретном случае, вызывается функция библиотеки.
Вне строгого режима ISO C (-ansi, -std=c90, -std=c99 или -std=c11), функции _exit, alloca, bcmp, bzero, dcgettext, dgettext, dremf, dreml, drem, exp10f, exp10l, exp10, ffsll, ffsl, ffs, fprintf_unlocked, fputs_unlocked, gammaf, gammal, gamma, gammaf_r, gammal_r, gamma_r, gettext, index, isascii, j0f, j0l, j0, j1f, j1l, j1, jnf, jnl, jn, lgammaf_r, lgammal_r, lgamma_r, mempcpy, pow10f, pow10l, pow10, printf_unlocked, rindex, scalbf, scalbl, scalb, signbit, signbitf, signbitl, signbitd32, signbitd64, signbitd128, significandf, significandl, significand, sincosf, sincosl, sincos, stpcpy, stpncpy, strcasecmp, strdup, strfmon, strncasecmp, strndup, 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_.
Функции ISO C94 iswalnum, iswalpha, iswcntrl, iswdigit, iswgraph, iswlower, iswprint, iswpunct, iswspace, iswupper, iswxdigit, towlower и towupper обрабатываются как встроенные функции, за исключением строгого режима ISO C90 (-ansi или -std=c90).
Функции ISO C90 abort, abs, acos, asin, atan2, atan, calloc, ceil, cosh, cos, exit, exp, fabs, floor, fmod, fprintf, fputs, frexp, fscanf, isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, tolower, toupper, labs, ldexp, log10, log, malloc, memchr, memcmp, memcpy, memset, modf, pow, printf, putchar, puts, scanf, sinh, sin, snprintf, sprintf, sqrt, sscanf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, tanh, tan, vfprintf, vprintf и vsprintf распознаются как встроенные функции, если не указано -fno-builtin (или для отдельной функции указано -fno-builtin-function). У всех этих функций есть соответствующие версии с префиксом __builtin_.
GCC предоставляет встроенные версии макросов сравнения чисел с плавающей точкой ISO C99, которые не генерируют исключения для неупорядоченных операндов. Они имеют те же имена, что и стандартные макросы (isgreater, isgreaterequal, isless, islessequal, islessgreater, и isunordered), с префиксом __builtin_. Мы предполагаем, что разработчик библиотеки сможет просто заменить каждый стандартный макрос на его встроенный аналог. Аналогично, GCC предоставляет встроенные функции fpclassify, isfinite, isinf_sign и isnormal, используемые с префиксом __builtin_. Встроенные функции isinf и isnan появляются как с, так и без префикса __builtin_.
Вы можете использовать встроенную функцию
__builtin_types_compatible_pдля определения, совпадают ли два типа.Эта встроенная функция возвращает 1, если неквалифицированные версии типов type1 и type2 (которые являются типами, а не выражениями) совместимы, и 0 в противном случае. Результат этой встроенной функции может быть использован в целочисленных константных выражениях.
Эта встроенная функция игнорирует квалификаторы верхнего уровня (например,
const,volatile). Например,intэквивалентноconst int.Тип
int[]иint[5]совместимы. С другой стороны,intиchar *несовместимы, даже если размер их типов на конкретной архитектуре одинаков. Также при определении сходства учитывается количество косвенных указателей. Следовательно,short *не подобенshort **. Кроме того, два типа, которые определены как typedef, считаются совместимыми, если их базовые типы совместимы.Тип
enumне считается совместимым с другим типомenum, даже если оба совместимы с одним целочисленным типом; это то, что определено стандартом C. Например,enum {foo, bar}не подобенenum {hot, dog}.Обычно вы используете эту функцию в коде, выполнение которого зависит от типов аргументов. Например:
#define foo(x) \ ({ \ typeof (x) tmp = (x); \ if (__builtin_types_compatible_p (typeof (x), long double)) \ tmp = foo_long_double (tmp); \ else if (__builtin_types_compatible_p (typeof (x), double)) \ tmp = foo_double (tmp); \ else if (__builtin_types_compatible_p (typeof (x), float)) \ tmp = foo_float (tmp); \ else \ abort (); \ tmp; \ })Примечание: Этот конструкт доступен только для C.
Вы можете использовать встроенную функцию
__builtin_choose_exprдля выполнения кода в зависимости от значения константного выражения. Эта встроенная функция возвращает exp1, если const_exp, которое является целочисленным константным выражением, не равно нулю. В противном случае она возвращает exp2.Эта встроенная функция аналогична оператору ‘
? :’ в C, за исключением того, что тип возвращаемого выражения не изменяется правилами преобразования. Также встроенная функция не вычисляет выражение, которое не выбрано. Например, если const_exp вычисляется как истинное, exp2 не вычисляется, даже если оно имеет побочные эффекты.Эта встроенная функция может возвращать lvalue, если выбранный аргумент является lvalue.
Если возвращается exp1, тип возврата совпадает с типом exp1. Аналогично, если возвращается exp2, его тип возврата совпадает с типом exp2.
Пример:
#define foo(x) \ __builtin_choose_expr ( \ __builtin_types_compatible_p (typeof (x), double), \ foo_double (x), \ __builtin_choose_expr ( \ __builtin_types_compatible_p (typeof (x), float), \ foo_float (x), \ /* The void expression results in a compile-time error \ when assigning the result to something. */ \ (void)0))Примечание: Этот конструкт доступен только для C. Кроме того, неиспользуемое выражение (exp1 или exp2 в зависимости от значения const_exp) всё ещё может генерировать синтаксические ошибки. Это может измениться в будущих версиях.
Встроенная функция
__builtin_complexпредназначена для использования при реализации макросов ISO C11CMPLXF,CMPLXиCMPLXL. real и imag должны иметь один и тот же тип, реальный двоичный тип с плавающей точкой, а результат имеет соответствующий комплексный тип с действительной и мнимой частями real и imag. В отличие от ‘real + I * imag’, это работает даже при наличии бесконечностей, NaN и отрицательных нулей.
Вы можете использовать встроенную функцию
__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 должен быть более осторожным при оценке встроенной функции в этом случае, потому что у него нет возможности выполнить оптимизацию.Предыдущие версии GCC не принимали эту встроенную функцию в инициализаторах данных. Самая ранняя версия, где это полностью безопасно, — 3.0.1.
Вы можете использовать
__builtin_expectдля предоставления компилятору информации о прогнозировании ветвления. В общем случае вы должны предпочесть использование фактической обратной связи профилирования для этого (-fprofile-arcs), так как программисты обычно плохо предсказывают, как фактически выполняется их программа. Однако есть приложения, в которых получение этих данных затруднено.Значение возврата — значение exp, которое должно быть целочисленным выражением. Семантика встроенной функции заключается в том, что ожидается, что exp == c. Например:
if (__builtin_expect (x, 0)) foo ();указывает, что мы не ожидаем вызова
foo, поскольку ожидаем, чтоxбудет равно нулю. Поскольку вы ограничены целочисленными выражениями для exp, вы должны использовать конструкции, такие какif (__builtin_expect (ptr != NULL, 1)) foo (*ptr);при проверке указателей или значений с плавающей точкой.
Эта функция вызывает аномальный выход программы. GCC реализует эту функцию, используя зависимый от целевой платформы механизм (например, преднамеренно выполняя незаконную инструкцию) или вызывая
abort. Использованный механизм может отличаться от релиза к релизу, поэтому вы не должны полагаться на какую-либо конкретную реализацию.
Если поток управления доходит до точки
__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 (); } }
Эта функция возвращает свой первый аргумент и позволяет компилятору предположить, что возвращаемый указатель выровнен по крайней мере на 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 байта.
Эта функция эквивалентна макросу препроцессора
__LINE__и возвращает номер строки вызова встроенной функции. В C++ по умолчанию аргумент функции F получает номер строки вызова F.
Эта функция эквивалентна макросу препроцессора
__FUNCTION__и возвращает имя функции, в которой происходит вызов встроенной функции.
Эта функция эквивалентна макросу препроцессора
__FILE__и возвращает имя файла, в котором происходит вызов встроенной функции. В C++ по умолчанию аргумент функции F получает имя файла вызова F.
Эта функция используется для очистки кэша инструкций процессора для области памяти между begin включительно и end не включительно. Некоторые целевые платформы требуют очистки кэша инструкций после изменения памяти, содержащей код, для получения детерминированного поведения.
Если целевая платформа не требует очистки кэша инструкций,
__builtin___clear_cacheне оказывает никакого влияния. В противном случае либо генерируются инструкции для очистки кэша инструкций, либо происходит вызов функции__clear_cacheв libgcc.
Эта функция используется для минимизации задержки промаха кэша, перемещая данные в кэш до обращения к ним. Вы можете вставлять вызовы
__builtin_prefetchв код, для которого вы знаете адреса данных в памяти, которые, вероятно, будут обработаны в ближайшее время. Если целевая платформа их поддерживает, генерируются инструкции предварительной выборки данных. Если предварительная выборка выполняется достаточно рано перед обращением, то данные окажутся в кэше к моменту обращения.Значение addr — адрес памяти для предварительной выборки. Есть два необязательных аргумента, rw и locality. Значение rw — константа времени компиляции 1 или 0; 1 означает, что предварительная выборка готовится к записи в адрес памяти, а 0, по умолчанию, означает, что предварительная выборка готовится к чтению. Значение locality должно быть целочисленной константой времени компиляции от 0 до 3. Значение 0 означает, что данные не имеют временной локальности, поэтому их не нужно оставлять в кэше после обращения. Значение 3 означает, что данные имеют высокую степень временной локальности и должны оставаться во всех уровнях кэша, насколько это возможно. Значения 1 и 2 означают соответственно низкую или умеренную степень временной локальности. По умолчанию используется 3.
for (i = 0; i < n; i++) { a[i] = a[i] + b[i]; __builtin_prefetch (&a[i+j], 1, 1); __builtin_prefetch (&b[i+j], 0, 1); /* ... */ }Предварительная выборка данных не генерирует исключения, если addr недействителен, но само выражение адреса должно быть действительным. Например, предварительная выборка
p->nextне вызывает исключение, еслиp->nextне является действительным адресом, но вычисление вызывает исключение, еслиpне является действительным адресом.Если целевая платформа не поддерживает предварительную выборку данных, выражение адреса оценивается, если оно включает побочные эффекты, но другой код не генерируется, и GCC не выдает предупреждение.
Возвращает положительную бесконечность, если это поддерживается форматом с плавающей точкой, иначе
DBL_MAX. Эта функция подходит для реализации макроса ISO CHUGE_VAL.
Аналогично
__builtin_huge_val, за исключением того, что тип возвращаемого значенияfloat.
Аналогично
__builtin_huge_val, за исключением того, что тип возвращаемого значенияlong double.
Эта встроенная функция реализует функциональность C99 fpclassify. Первые пять аргументов int должны быть представлениями возможных классов FP в целевой библиотеке и используются для значений возврата. Они должны быть константами и должны появляться в этом порядке:
FP_NAN,FP_INFINITE,FP_NORMAL,FP_SUBNORMALиFP_ZERO. Эллипсис предназначен для одного значения с плавающей точкой для классификации. GCC рассматривает последний аргумент как тип-обобщение, что означает, что он не выполняет автоматическое преобразование типа float в double.
Аналогично
__builtin_huge_val, за исключением того, что генерируется предупреждение, если целевой формат с плавающей точкой не поддерживает бесконечности.
Аналогично
__builtin_inf, за исключением того, что тип возвращаемого значения_Decimal32.
Аналогично
__builtin_inf, за исключением того, что тип возвращаемого значения_Decimal64.
Аналогично
__builtin_inf, за исключением того, что тип возвращаемого значения_Decimal128.
Аналогично
__builtin_inf, за исключением того, что тип возвращаемого значенияfloat. Эта функция подходит для реализации макроса ISO C99INFINITY.
Аналогично
__builtin_inf, за исключением того, что тип возвращаемого значенияlong double.
Аналогично
isinf, за исключением того, что значение возврата равно -1 для аргумента-Infи 1 для аргумента+Inf. Обратите внимание, что хотя список параметров — эллипсис, эта функция принимает только один аргумент с плавающей точкой. GCC обрабатывает этот параметр как тип-обобщение, что означает, что он не выполняет автоматическое преобразование типа float в double.
Это реализация функции ISO C99
nan.Поскольку ISO C99 определяет эту функцию с точки зрения
strtod, которую мы не реализуем, необходимо описать процесс парсинга. Строка парсится как поstrtol; то есть, основание распознается префиксами «0» или «0x». Парсируемое число размещается в мантиссе так, что самый младший бит числа находится в самом младшем бите мантиссы. Число усекается, чтобы поместиться в поле мантиссы. Мантисса принудительно устанавливается в тип бесшумной NaN.Эта функция, если ей передаётся строковая константа, вся которая будет использована
strtol, вычисляется достаточно рано, чтобы её можно было считать константой времени компиляции.
Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значения_Decimal32.
Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значения_Decimal64.
Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значения_Decimal128.
Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значенияfloat.
Аналогично
__builtin_nan, за исключением того, что тип возвращаемого значенияlong double.
Аналогично
__builtin_nan, за исключением того, что мантисса принудительно устанавливается в тип сигнализирующей NaN. Функцияnansпредложена в WG14 N965.
Аналогична
__builtin_nans, за исключением того, что тип возвращаемого значения —float.
Аналогична
__builtin_nans, за исключением того, что тип возвращаемого значения —long double.
Возвращает значение, равное единице плюс индекс младшего значащего бита x, или ноль, если x равно нулю.
Возвращает количество ведущих нулевых битов в x, начиная с самого старшего разряда. Если x равно 0, результат не определён.
Возвращает количество младших значащих нулевых битов в x, начиная с младшего разряда. Если x равно 0, результат не определён.
Возвращает количество ведущих избыточных знаковых битов в x, т. е. количество битов, следующих за старшим битом и идентичных ему. Нет особых случаев для 0 или других значений.
Возвращает количество единичных битов в x.
Возвращает чётность x, т. е. количество единичных битов в x по модулю 2.
Аналогична
__builtin_ffs, за исключением типа аргумента, который —long.
Аналогична
__builtin_clz, за исключением типа аргумента, который —unsigned long.
Аналогична
__builtin_ctz, за исключением типа аргумента, который —unsigned long.
Аналогична
__builtin_clrsb, за исключением типа аргумента, который —long.
Аналогична
__builtin_popcount, за исключением типа аргумента, который —unsigned long.
Аналогична
__builtin_parity, за исключением типа аргумента, который —unsigned long.
Аналогична
__builtin_ffs, за исключением типа аргумента, который —long long.
Аналогична
__builtin_clz, за исключением типа аргумента, который —unsigned long long.
Аналогична
__builtin_ctz, за исключением типа аргумента, который —unsigned long long.
Аналогична
__builtin_clrsb, за исключением типа аргумента, который —long long.
Аналогична
__builtin_popcount, за исключением типа аргумента, который —unsigned long long.
Аналогична
__builtin_parity, за исключением типа аргумента, который —unsigned long long.
Возвращает первое число, возведённое в степень второго. В отличие от функции
pow, не гарантируется точность и округление.
Аналогична
__builtin_powi, за исключением типов аргументов и возвращаемого значения, которые —float.
Аналогична
__builtin_powi, за исключением типов аргументов и возвращаемого значения, которые —long double.
Возвращает x с переставленным порядком байтов; например,
0xaabbстановится0xbbaa. Байтом здесь всегда является ровно 8 бит.
Аналогична
__builtin_bswap16, за исключением того, что типы аргумента и возвращаемого значения — 32-битные.
Аналогична
__builtin_bswap32, за исключением того, что типы аргумента и возвращаемого значения — 64-битные.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Other-Builtins.html