7.12 Другие встроенные функции, предоставляемые GCC
В этом разделе описаны различные встроенные функции, доступные в GCC.
-
Встроенная функция:
bool__builtin_has_attribute(type-or-expression, attribute) -
Функция
__builtin_has_attributeвычисляет целочисленное константное выражение, равноеtrue, если символ или тип, на который ссылается аргумент type-or-expression, был объявлен с атрибутом attribute, указанным во втором аргументе. Если аргумент 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_choose_expr(const_exp, exp1, exp2) -
Встроенную функцию
__builtin_choose_exprможно использовать для вычисления кода в зависимости от значения константного выражения. Эта встроенная функция возвращает exp1, если const_exp, являющееся целочисленным константным выражением, не равно нулю. В противном случае она возвращает exp2.Как и оператор ‘? :’, эта встроенная функция не вычисляет невыбранное выражение. Например, если const_exp вычисляется в
true, exp2 не вычисляется, даже если оно имеет побочные эффекты. С другой стороны,__builtin_choose_exprотличается от ‘? :’ тем, что первый операнд должен быть константой времени компиляции, а к остальным операндам не применяются ограничения и правила продвижения типов оператора ‘? :’.Эта встроенная функция может возвращать 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.Для определения общего типа u по типам аргументов параметров, типы которых различаются у разных функций, используются стандартные правила для макросов
<tgmath.h>; комплексные целочисленные типы (расширение GNU) рассматриваются как комплексный тип, соответствующий вещественному типу с плавающей точкой, который был бы выбран для соответствующего вещественного целочисленного типа. Если возвращаемые типы функций различаются или все являются одним и тем же целочисленным типом, вызывается функция, для которой t равно u; если такой функции нет, возникает ошибка. Если возвращаемые типы всех функций — один и тот же тип с плавающей точкой, обобщённый по типу макрос считается одним из макросов TS 18661, округляющих результат до более узкого типа. Если существует функция, для которой t равно u, вызывается она; в противном случае вызывается первая функция (если таковая имеется), для которой диапазон и точность t не меньше, чем у u. Если такой функции нет, возникает ошибка.
-
Встроенная функция:
int__builtin_constant_p(exp) -
Встроенную функцию
__builtin_constant_pможно использовать, чтобы определить, известно ли во время компиляции, что выражение exp является константой, и, следовательно, может ли GCC свернуть константы в выражениях с этим значением. Аргумент функции — выражение, которое требуется проверить. Выражение не вычисляется, побочные эффекты отбрасываются. Функция возвращает целое число 1, если известно, что аргумент является константой времени компиляции, и 0, если это неизвестно. Любое выражение с побочными эффектами заставляет функцию вернуть 0. Возврат 0 не означает, что выражение не является константой; это лишь означает, что GCC не может доказать, что оно является константой, в рамках активного набора параметров оптимизации.Обычно эта функция используется во встроенных приложениях, где память является критически важным ресурсом. Если требуется выполнить сложное вычисление, можно свернуть его, когда оно включает константы, но вызвать функцию, если это не так. Например:
#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++. Эта встроенная функция предназначена для использования в реализациях функции C++std::is_constant_evaluated. Вместо прямого вызова встроенной функции программам следует использовать эту функцию.Основной вариант использования встроенной функции — определить, вызывается ли функция
constexprв контекстеconstexpr. Вызов функции вычисляется как основное константное выражение со значениемtrueтогда и только тогда, когда он происходит при вычислении выражения или преобразования, явно вычисляемого как константа согласно определению в стандарте C++. К контекстам явного вычисления констант относятся константные выражения, условия операторовconstexpr if, выражения-ограничения и инициализаторы переменных, используемых в константных выражениях. Дополнительные сведения см. в последней редакции стандарта C++.
-
Встроенная функция:
type__builtin_counted_by_ref(ptr) -
Встроенная функция
__builtin_counted_by_refпроверяет, связан ли с объектом массива, на который указывает указатель ptr, другой объект, представляющий число элементов этого массива с помощью атрибутаcounted_by(то есть объект counted-by). Если такой объект существует, функция возвращает указатель на соответствующий объект counted-by. Если такого объекта нет, функция возвращает нулевой указатель.На данный момент эта встроенная функция доступна только в C.
Аргумент ptr должен быть указателем на массив. type возвращаемого значения — это тип указателя на соответствующий тип объекта counted-by либо тип указателя void, если возвращается нулевой указатель.
Например:
struct foo1 { int counter; struct bar1 array[] __attribute__((counted_by (counter))); } *p; struct foo2 { int other; struct bar2 array[]; } *q;следующий вызов встроенной функции:
__builtin_counted_by_ref (p->array)
возвращает:
&p->counter with type
int *.Однако следующий вызов встроенной функции:
__builtin_counted_by_ref (q->array)
возвращает нулевой указатель на
void.
-
Встроенная функция:
void__builtin_clear_padding(ptr) -
Встроенная функция
__builtin_clear_paddingочищает биты заполнения во внутреннем представлении объекта, на который указывает ptr; это значение должно быть указателем. Представление значения объекта не изменяется. Предполагается, что тип объекта совпадает с типом, на который указывает указатель. Внутри объединения очищаются только те биты, которые являются битами заполнения для всех его членов.Эта встроенная функция полезна, если биты заполнения объекта могут иметь неопределённые значения и требуется побитовое сравнение представления объекта с другим объектом, например при атомарных операциях.
В C++ тип аргумента ptr должен быть указателем на тривиально копируемый тип, если только аргумент не является адресом переменной или параметра. В противном случае неизвестно, не является ли этот тип просто базовым классом, биты заполнения которого повторно используются или иначе размещаются в производном классе.
-
Встроенная функция:
type__builtin_bit_cast(type, arg) -
Функция
__builtin_bit_castдоступна только в C++. Эта встроенная функция предназначена для использования в реализациях шаблонной функции C++std::bit_cast. Вместо прямого вызова встроенной функции программам следует использовать эту функцию.Эта встроенная функция позволяет интерпретировать биты аргумента 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, задаётся параметром GCCbuiltin-expect-probability, который по умолчанию равен 90%.Также можно использовать
__builtin_expect_with_probabilityдля явного назначения значения вероятности отдельным выражениям. Если встроенная функция используется в цикле, заданная вероятность влияет на ожидаемое число итераций, определяемое оптимизациями циклов.
-
Встроенная функция:
long__builtin_expect_with_probability -
(long exp, long c, double probability)
Семантика этой функции совпадает с семантикой
__builtin_expect, но вызывающий код задаёт ожидаемую вероятность того, что exp == c. Последний аргумент, probability, — это значение с плавающей точкой в диапазоне от 0.0 до 1.0 включительно. Аргумент probability должен быть константным выражением с плавающей точкой.
-
Встроенная функция:
void__builtin_trap(void) Эта функция аварийно завершает программу. GCC реализует её с помощью зависящего от целевой платформы механизма (например, намеренного выполнения недопустимой инструкции) или вызова
abort. Используемый механизм может меняться от версии к версии, поэтому не следует полагаться на какую-либо конкретную реализацию.
-
Встроенная функция:
void__builtin_unreachable(void) -
Если управление доходит до места вызова
__builtin_unreachable, поведение программы не определено. Эта функция полезна в ситуациях, когда компилятор не может самостоятельно определить, что код недостижим.Один из таких случаев — вызов сразу после оператора
asm, который либо никогда не завершается, либо передаёт управление в другое место и не возвращается. В этом примере без__builtin_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 (); } }
-
Встроенная функция:
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— нельзя.Барьер также имеет значение, когда активен параметр
-ffp-contract=fast; он предотвращает объединение выражений.float x0 = a * b + c; float x1 = __builtin_assoc_barrier (a * b) + c;
это означает, что при
-ffp-contract=fastвыражениеx0можно оптимизировать с использованием инструкции слитного умножения-сложения, но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 — это целочисленная константа времени компиляции со значением ноль, один или два; единица означает, что предварительная выборка готовит данные к записи по этому адресу, двойка означает, что она готовит данные к совместному чтению (предполагается, что до записи, если она вообще произойдёт, данные прочитает как минимум ещё один процессор), а ноль, используемый по умолчанию, означает, что предварительная выборка готовит данные к чтению. Значение 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 не выдаёт предупреждение.
-
Встроенная функция:
int__builtin_classify_type(arg) -
Встроенная функция:
int__builtin_classify_type(type) -
Функция
__builtin_classify_typeвозвращает небольшое целое число, обозначающее категорию типа аргумента arg: например, тип void, целочисленный тип, перечислимый тип, логический тип, тип указателя, ссылочный тип, тип смещения, вещественный тип, комплексный тип, тип функции, тип метода, тип структуры, тип объединения, тип массива, строковый тип, целочисленный тип с точной разрядностью, векторный тип и т. д. Если аргумент является выражением, для обеспечения обратной совместимости он подвергается продвижению типов, как аргументы, передаваемые в...вариативной функции, поэтому в некоторых языках некоторые категории никогда не возвращаются. В качестве альтернативы аргументом встроенной функции может быть имя типа, например спецификаторtypeof.int a[2]; __builtin_classify_type (a) == __builtin_classify_type (int[5]); __builtin_classify_type (a) == __builtin_classify_type (void*); __builtin_classify_type (typeof (a)) == __builtin_classify_type (int[5]);
Первое сравнение никогда не будет истинным, поскольку a неявно преобразуется в указатель. Последние два сравнения будут истинными, поскольку во втором случае определяется категория указателей, а в последнем — массивов.
-
Встроенная функция:
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-15.3.0/gcc/Other-Builtins.html