Spec-Zone.ru › GCC 15

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 может быть любым целочисленным типом или типом указателя.

  1. Если ЦП не выполняет код спекулятивно, возвращается val.
  2. Если ЦП выполняет код спекулятивно, возможно одно из двух:
    • Функция может приостановить выполнение до тех пор, пока не станет известно, что код больше не выполняется спекулятивно (в этом случае, как и выше, может быть возвращено val); либо
    • Функция может использовать зависящее от целевой платформы состояние отслеживания спекулятивного выполнения и вернуть failval, когда станет известно, что спекулятивное выполнение неверно предсказало операцию условного перехода.

Второй аргумент, failval, необязателен и по умолчанию равен нулю, если он не указан.

Для целевых платформ, обновлённых для поддержки этой встроенной функции, GCC определяет макрос препроцессора __HAVE_BUILTIN_SPECULATION_SAFE_VALUE.

Встроенную функцию можно использовать, когда переменная, по-видимому, используется безопасным образом, однако ЦП из-за спекулятивного выполнения может временно игнорировать проверки границ. Рассмотрим, например, следующую функцию:

int array[500];
int f (unsigned untrusted_index)
{
  if (untrusted_index < 500)
    return array[untrusted_index];
  return 0;
}

Если функция многократно вызывается с untrusted_index меньше предельного значения 500, предсказатель переходов запомнит, что будет выполняться блок кода, возвращающий значение, хранящееся в array. Если затем функция будет вызвана со значением вне диапазона, она всё равно сначала попытается выполнить этот блок кода, пока ЦП не определит, что предсказание было неверным (после этого ЦП отменит все ошибочные операции). Однако, в зависимости от использования результата функции, в кэше могут остаться следы, позволяющие узнать, что хранилось за пределами допустимой области. Встроенную функцию можно использовать для некоторой защиты от утечки данных таким способом, изменив код следующим образом:

int array[500];
int f (unsigned untrusted_index)
{
  if (untrusted_index < 500)
    return array[__builtin_speculation_safe_value (untrusted_index)];
  return 0;
}

Встроенная функция либо остановит выполнение до полного разрешения условного перехода, либо позволит продолжить спекулятивное выполнение, но будет использовать 0 вместо untrusted_value, если оно превышает предельное значение.

Если при ошибочном спекулятивном выполнении обращение к любой ячейке памяти потенциально небезопасно, код можно переписать следующим образом:

int array[500];
int f (unsigned untrusted_index)
{
  if (untrusted_index < 500)
    return *__builtin_speculation_safe_value (&array[untrusted_index], NULL);
  return 0;
}

в этом случае для небезопасного варианта будет использоваться указатель NULL.

Встроенная функция: int __builtin_types_compatible_p (type1, type2)

Встроенную функцию __builtin_types_compatible_p можно использовать для определения того, являются ли два типа одинаковыми.

Эта встроенная функция возвращает 1, если типы type1 и type2 без квалификаторов (это типы, а не выражения) совместимы, и 0 в противном случае. Результат этой встроенной функции можно использовать в целочисленных константных выражениях.

Эта встроенная функция игнорирует квалификаторы верхнего уровня (например, const, volatile). Например, int эквивалентно const int.

Типы int[] и int[5] совместимы. С другой стороны, int и char * несовместимы, даже если размер их типов на конкретной архитектуре одинаков. При определении сходства также учитывается уровень косвенности указателей. Следовательно, short * не подобен short **. Кроме того, два типа, заданные через typedef, считаются совместимыми, если совместимы их базовые типы.

Тип enum не считается совместимым с другим типом enum, даже если оба совместимы с одним и тем же целочисленным типом; именно это предписывает стандарт C. Например, enum {foo, bar} не подобен enum {hot, dog}.

Обычно эта функция используется в коде, выполнение которого зависит от типов аргументов. Например:

#define foo(x)                                                  \
  ({                                                           \
    typeof (x) tmp = (x);                                       \
    if (__builtin_types_compatible_p (typeof (x), long double)) \
      tmp = foo_long_double (tmp);                              \
    else if (__builtin_types_compatible_p (typeof (x), double)) \
      tmp = foo_double (tmp);                                   \
    else if (__builtin_types_compatible_p (typeof (x), float))  \
      tmp = foo_float (tmp);                                    \
    else                                                        \
      abort ();                                                 \
    tmp;                                                        \
  })

Примечание: эта конструкция доступна только в C.

Встроенная функция: 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, задаётся параметром GCC builtin-expect-probability, который по умолчанию равен 90%.

Также можно использовать __builtin_expect_with_probability для явного назначения значения вероятности отдельным выражениям. Если встроенная функция используется в цикле, заданная вероятность влияет на ожидаемое число итераций, определяемое оптимизациями циклов.

Встроенная функция: long __builtin_expect_with_probability

(long exp, long c, double probability)

Семантика этой функции совпадает с семантикой __builtin_expect, но вызывающий код задаёт ожидаемую вероятность того, что exp == c. Последний аргумент, probability, — это значение с плавающей точкой в диапазоне от 0.0 до 1.0 включительно. Аргумент probability должен быть константным выражением с плавающей точкой.

Встроенная функция: void __builtin_trap (void)

Эта функция аварийно завершает программу. GCC реализует её с помощью зависящего от целевой платформы механизма (например, намеренного выполнения недопустимой инструкции) или вызова abort. Используемый механизм может меняться от версии к версии, поэтому не следует полагаться на какую-либо конкретную реализацию.

Встроенная функция: void __builtin_unreachable (void)

Если управление доходит до места вызова __builtin_unreachable, поведение программы не определено. Эта функция полезна в ситуациях, когда компилятор не может самостоятельно определить, что код недостижим.

Один из таких случаев — вызов сразу после оператора asm, который либо никогда не завершается, либо передаёт управление в другое место и не возвращается. В этом примере без __builtin_unreachable GCC выдаёт предупреждение о том, что управление достигает конца функции с возвращаемым значением. Кроме того, он генерирует код возврата после asm.

int f (int c, int v)
{
  if (c)
    {
      return v;
    }
  else
    {
      asm("jmp error_handler");
      __builtin_unreachable ();
    }
}

Поскольку оператор asm безусловно передаёт управление за пределы функции, управление никогда не достигает конца тела функции. Вызов __builtin_unreachable действительно недостижим и сообщает об этом компилятору.

Ещё один вариант использования __builtin_unreachable — размещение после вызова функции, которая никогда не возвращается, но не объявлена как __attribute__((noreturn)), как в этом примере:

void function_that_never_returns (void);

int g (int c)
{
  if (c)
    {
      return 1;
    }
  else
    {
      function_that_never_returns ();
      __builtin_unreachable ();
    }
}
Встроенная функция: 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

Spec-Zone.ru

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