Spec-Zone.ru › GCC 12

6.33.1 Общие атрибуты функций

Следующие атрибуты поддерживаются на большинстве целевых платформ.

access (access-mode, ref-index)
access (access-mode, ref-index, size-index)

Атрибут access позволяет обнаруживать некорректные или небезопасные обращения функций, к которым он применяется, или их вызывающих функций, а также операции записи в объекты, которые никогда не читаются. Такие обращения могут быть диагностированы предупреждениями, такими как -Wstringop-overflow, -Wuninitialized, -Wunused и другими.

Атрибут access указывает, что функция, к аргументам которой по ссылке применяется атрибут, обращается к объекту по ссылке в соответствии с access-mode. Аргумент access-mode является обязательным и должен быть одним из четырёх имён: read_only, read_write, write_only, или none. Остальные два — позиционные аргументы.

Обязательный позиционный аргумент ref-index обозначает аргумент функции типа указатель (или в C++, ссылка), к которому применяется обращение. Один и тот же аргумент-указатель может быть проиндексирован не более чем одним distinct атрибутом access.

Необязательный позиционный аргумент size-index обозначает аргумент функции целочисленного типа, который определяет максимальный размер обращения. Размер — это количество элементов типа, на который ссылается ref-index, или количество байтов, когда тип указателя — void*. Если аргумент size-index не указан, аргумент-указатель должен быть либо нулевым, либо указывать на область памяти, которая достаточно выровнена и велика для хотя бы одного объекта указанного типа (это подразумевает, что указатель, указывающий за границами памяти, не является допустимым аргументом). Фактический размер обращения может быть меньше, но не больше.

Режим доступа read_only указывает, что указатель, к которому он применяется, используется для чтения объекта по ссылке, но не для записи в него. Если аргумент, определяющий размер доступа, обозначаемый size-index, не равен нулю, объект по ссылке должен быть инициализирован. Этот режим подразумевает более сильную гарантию, чем квалификатор const, который, при приведении указателя, не препятствует изменению объекта, на который он указывает. Примеры использования режима доступа read_only — аргумент функции puts, или второй и третий аргументы функции memcpy.

__attribute__ ((access (read_only, 1))) int puts (const char*);
__attribute__ ((access (read_only, 2, 3))) void* memcpy (void*, const void*, size_t);

Режим доступа read_write применяется к аргументам типа указатель без квалификатора const. Он указывает, что указатель, к которому он применяется, используется для чтения и записи в объект по ссылке. Если аргумент, определяющий размер доступа, обозначаемый size-index, не равен нулю, объект, на который указывает указатель, должен быть инициализирован. Пример использования режима доступа read_write — первый аргумент функции strcat.

__attribute__ ((access (read_write, 1), access (read_only, 2))) char* strcat (char*, const char*);

Режим доступа write_only применяется к аргументам типа указатель без квалификатора const. Он указывает, что указатель, к которому он применяется, используется для записи в объект по ссылке, но не для чтения из него. Объект, на который указывает указатель, не обязательно должен быть инициализирован. Пример использования режима доступа write_only — первый аргумент функции strcpy, или первые два аргумента функции fgets.

__attribute__ ((access (write_only, 1), access (read_only, 2))) char* strcpy (char*, const char*);
__attribute__ ((access (write_only, 1, 2), access (read_write, 3))) int fgets (char*, int, FILE*);

Режим доступа none указывает, что указатель, к которому он применяется, вообще не используется для доступа к объекту по ссылке. Если указатель не нулевой, объект, на который он указывает, должен существовать и иметь размер, как указано в аргументе size-index. Если необязательный аргумент size-index опущен для аргумента типа void*, фактический аргумент указателя игнорируется. Ссылаемый объект не обязательно должен быть инициализирован. Этот режим предназначен для проверки ожидаемого размера объекта, например, в функциях, которые вызывают __builtin_object_size. См. Проверку размера объекта.

Обратите внимание, что атрибут access лишь определяет, как можно получить доступ к объекту по ссылке, на который указывает аргумент-указатель; он не подразумевает, что доступ будет произведён. Также атрибут access не подразумевает атрибут nonnull; может быть целесообразно добавить оба атрибута к объявлению функции, которая безусловно манипулирует буфером через аргумент-указатель. Для получения дополнительной информации и замечаний см. атрибут nonnull.

alias ("target")

Атрибут alias заставляет объявление генерировать алиас для другой переменной, которая должна быть предварительно объявлена со stej типом, а для переменных — также с тем же размером и выравниванием. Объявление алиаса с другим типом, чем целевой, является неопределённым и может быть диагностировано. Например, следующие объявления:

void __f () { /* Do something. */; }
void f () __attribute__ ((weak, alias ("__f")));

определяют ‘f’ как слабый алиас для ‘__f’. В C++, должно использоваться имя, полученное при преобразовании в функцию.

Если ‘__f’ не определена в том же модуле, это ошибка.

Данный атрибут требует поддержки со стороны ассемблера и файла объектов и может быть недоступен на всех целевых платформах.

aligned
aligned (alignment)

Атрибут aligned задаёт минимальное выравнивание для первого машинного кода функции в байтах. Если указан, alignment должен быть целым числом, являющимся степенью двойки. Если аргумент alignment отсутствует, предполагается идеальное выравнивание для целевой платформы. Оператор __alignof__ может быть использован для определения этого значения (см. Выравнивание). Атрибут не имеет эффекта, если определение функции не представлено в том же модуле.

Атрибут нельзя использовать для уменьшения выравнивания функции, ранее объявленной с более строгим выравниванием; его можно только увеличить. Попытки сделать обратное будут диагностированы. Некоторые целевые платформы устанавливают минимальное значение выравнивания для функций, которое больше 1. На таких платформах, установка менее строгого выравнивания игнорируется. Использование атрибута перезаписывает влияние опции -falign-functions (см. Опции оптимизации) для этой функции.

Обратите внимание, что эффективность атрибутов aligned может быть ограничена системными ограничениями компоновщика и/или формата файлов объектов. На некоторых системах компоновщик может выровнять функции только до определённого максимального значения выравнивания. (Для некоторых компоновщиков максимальное поддерживаемое выравнивание может быть очень низким.) Обратитесь к документации вашего компоновщика для получения дополнительной информации.

Атрибут aligned также может быть применён к переменным и полям (см. Атрибуты переменных).

alloc_align (position)

Атрибут alloc_align может быть применён к функции, возвращающей указатель и принимающей по меньшей мере один аргумент целочисленного или перечислимого типа. Он указывает, что возвращаемый указатель выровнен на границе, заданной аргументом функции в position. Значимые значения выравнивания — степени двойки, большие единицы. GCC использует эту информацию для улучшения анализа выравнивания указателей.

Параметр функции, обозначающий выравнивание, задаётся одним целочисленным аргументом, число которого является аргументом атрибута. Номера аргументов начинаются с единицы.

Например,

void* my_memalign (size_t, size_t) __attribute__ ((alloc_align (1)));

указывает, что my_memalign возвращает память с минимальным выравниванием, заданным параметром 1.

alloc_size (position)
alloc_size (position-1, position-2)

Атрибут alloc_size может быть применён к функции, возвращающей указатель и принимающей по меньшей мере один аргумент целочисленного или перечислимого типа. Он указывает, что возвращаемый указатель указывает на память, размер которой задаётся аргументом функции в position-1 или произведением аргументов в position-1 и position-2. Значимые размеры — положительные значения, меньшие чем PTRDIFF_MAX. GCC использует эту информацию для улучшения результатов __builtin_object_size.

Параметр(ы) функции, обозначающие размер, задаются одним или двумя целочисленными аргументами, передаваемыми атрибуту. Выделенный размер — это либо значение единственного аргумента функции, либо произведение двух аргументов функции. Номера аргументов начинаются с единицы для обычных функций и с двойки для нестатических функций-членов C++.

Например,

void* my_calloc (size_t, size_t) __attribute__ ((alloc_size (1, 2)));
void* my_realloc (void*, size_t) __attribute__ ((alloc_size (2)));

указывает, что my_calloc возвращает память размером, равным произведению параметров 1 и 2, и что my_realloc возвращает память размером, заданным параметром 2.

always_inline

В общем случае функции не включаются в код, если не указана оптимизация. Для функций, объявленных как встроенные, этот атрибут включает функцию независимо от ограничений, которые обычно применяются к включению в код. Отсутствие включения такой функции диагностируется как ошибка. Обратите внимание, что если такая функция вызывается косвенно, компилятор может или не может включить её в код, в зависимости от уровня оптимизации, а отсутствие включения косвенного вызова может или не может быть диагностировано.

artificial

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

assume_aligned (alignment)
assume_aligned (alignment, offset)

Атрибут assume_aligned может быть применён к функции, возвращающей указатель. Он указывает, что возвращаемый указатель выровнен на границе, заданной alignment. Если у атрибута есть два аргумента, второй аргумент — смещение offset при невыравнивании. Значимые значения alignment — степени двойки, большие единицы. Значимые значения offset — больше нуля и меньше alignment.

Например,

void* my_alloc1 (size_t) __attribute__((assume_aligned (16)));
void* my_alloc2 (size_t) __attribute__((assume_aligned (32, 8)));

указывает, что my_alloc1 возвращает 16-байтовые выровненные указатели, и что my_alloc2 возвращает указатель, значение которого по модулю 32 равно 8.

cold
END_OF_DOCUMENT_MARKER

Атрибут cold для функций используется, чтобы сообщить компилятору, что функция вряд ли будет выполнена. Функция оптимизирована для размера, а не для скорости, и на многих целевых платформах она помещается в специальный подраздел секции кода, так что все холодные функции находятся близко друг к другу, улучшая локальность кода для нехолодных частей программы. Пути, ведущие к вызовам холодных функций в коде, помечаются как маловероятные механизмом предсказания ветвлений. Поэтому полезно помечать функции, используемые для обработки маловероятных условий, таких как perror, как холодные, чтобы улучшить оптимизацию горячих функций, которые в редких случаях вызывают помеченные функции.

Когда доступна обратная связь от профилирования, через -fprofile-use, холодные функции автоматически обнаруживаются, и этот атрибут игнорируется.

const

Вызовы функций, значения возврата которых не зависят от изменений наблюдаемого состояния программы и которые не оказывают наблюдаемого влияния на это состояние, кроме возврата значения, могут быть оптимизированы, например, устранением общих подвыражений. Объявление таких функций с атрибутом const позволяет GCC избегать вывода некоторых вызовов при повторных вызовах функции с одинаковыми значениями аргументов.

Например,

int square (int) __attribute__ ((const));

сообщает GCC, что последующие вызовы функции square с одинаковым значением аргумента могут быть заменены результатом первого вызова независимо от операторов между ними.

Атрибут const запрещает функции читать объекты, влияющие на её возвращаемое значение, между последовательными вызовами. Однако функции, объявленные с этим атрибутом, могут безопасно читать объекты, которые не изменяют их возвращаемое значение, такие как константы без побочных эффектов.

Атрибут const накладывает более строгие ограничения на определение функции, чем аналогичный атрибут pure. Объявление одной и той же функции с обоими атрибутами const и pure вызовет диагностику. Поскольку константная функция не может иметь никаких наблюдаемых побочных эффектов, для неё не имеет смысла возвращать void. Объявление такой функции вызовет диагностику.

Обратите внимание, что функция, имеющая указательные аргументы и проверяющая данные, на которые они указывают, не должна объявляться с атрибутом const, если указанные данные могут измениться между последовательными вызовами функции. В общем случае, поскольку функция не может отличить данные, которые могут измениться, от данных, которые не могут, константные функции никогда не должны принимать указательные или, в C++, ссылочные аргументы. Аналогично, функция, которая вызывает неконстантную функцию, обычно не должна быть константной.

constructor
destructor
constructor (priority)
destructor (priority)

Атрибут constructor вызывает автоматическое выполнение функции перед входом в main (). Аналогично, атрибут destructor вызывает автоматическое выполнение функции после завершения main () или вызова exit (). Функции с этими атрибутами полезны для инициализации данных, которые неявно используются во время выполнения программы.

На некоторых целевых платформах атрибуты также принимают целочисленный аргумент для указания приоритета, чтобы контролировать порядок выполнения конструкторов и деструкторов. Конструктор с меньшим номером приоритета выполняется до конструктора с большим номером приоритета; обратная зависимость имеет место для деструкторов. Обратите внимание, что приоритеты 0-100 зарезервированы. Таким образом, если у вас есть конструктор, который выделяет ресурс, и деструктор, который освобождает этот же ресурс, обе функции обычно имеют одинаковый приоритет. Приоритеты для конструкторов и деструкторов совпадают с теми, что указаны для объектов C++ на уровне пространства имён (см. Атрибуты C++). Однако в настоящее время порядок вызова конструкторов для объектов C++ со статической длиной хранения и функций, помеченных атрибутом constructor, не определён. В смешанных объявлениях атрибут init_priority может использоваться для навязывания определённого порядка.

Использование аргументных форм атрибутов constructor и destructor на целевых платформах, где данная функция не поддерживается, отклоняется с ошибкой.

copy
copy (function)

Атрибут copy применяет набор атрибутов, с которыми была объявлена функция function, к объявлению функции, к которой применяется атрибут. Атрибут предназначен для библиотек, которые определяют псевдонимы или решатели функций, которые должны указывать тот же набор атрибутов, что и их целевые функции. Атрибут copy может использоваться с функциями, переменными или типами. Однако тип символа, к которому применяется атрибут (функция или переменная), должен совпадать с типом символа, к которому относится аргумент. Атрибут copy копирует только синтаксические и семантические атрибуты, но не атрибуты, влияющие на связь или видимость символа, такие как alias, visibility, или weak. Атрибуты deprecated и target_clones также не копируются. См. Общие атрибуты типов. См. Общие атрибуты переменных.

Например, макрос StrongAlias ниже использует атрибуты alias и copy для определения псевдонима alloc для функции allocate, объявленной с атрибутами alloc_size, malloc и nothrow. Благодаря оператору __typeof__ псевдоним имеет тот же тип, что и целевая функция. В результате атрибута copy псевдоним также разделяет те же атрибуты, что и целевая функция.

#define StrongAlias(TargetFunc, AliasDecl)  \
  extern __typeof__ (TargetFunc) AliasDecl  \
    __attribute__ ((alias (#TargetFunc), copy (TargetFunc)));

extern __attribute__ ((alloc_size (1), malloc, nothrow))
  void* allocate (size_t);
StrongAlias (allocate, alloc);
deprecated
deprecated (msg)

Атрибут deprecated вызывает предупреждение, если функция используется где-либо в исходном файле. Это полезно для выявления функций, которые, как ожидается, будут удалены в будущей версии программы. Предупреждение также включает местоположение объявления устаревшей функции, что позволяет пользователям легко найти дополнительную информацию о том, почему функция устарела или что им следует сделать вместо неё. Обратите внимание, что предупреждения происходят только для использования:

int old_fn () __attribute__ ((deprecated));
int old_fn ();
int (*fn_ptr)() = old_fn;

приводит к предупреждению на строке 3, но не на строке 2. Необязательный аргумент msg, который должен быть строкой, выводится в предупреждении, если он присутствует.

Атрибут deprecated также может использоваться для переменных и типов (см. Атрибуты переменных, см. Атрибуты типов.)

Сообщение, прикреплённое к атрибуту, зависит от настройки параметра -fmessage-length.

unavailable
unavailable (msg)

Атрибут unavailable приводит к ошибке, если функция используется где-либо в исходном файле. Это полезно для выявления функций, удалённых из определённой вариации интерфейса. Помимо выдачи ошибки вместо предупреждения, атрибут unavailable ведёт себя аналогично атрибуту deprecated.

Атрибут unavailable также может использоваться для переменных и типов (см. Атрибуты переменных, см. Атрибуты типов.)

error ("message")
warning ("message")

Если атрибут error или warning используется в объявлении функции, и вызов этой функции не устраняется за счёт удаления неиспользуемого кода или других оптимизаций, диагностируется ошибка или предупреждение (соответственно), включающие message. Это полезно для проверки на этапе компиляции, особенно вместе с __builtin_constant_p и встроенными функциями, где проверка аргументов встроенной функции невозможна с помощью приёмов extern char [(condition) ? 1 : -1];.

Хотя возможно оставить функцию неопределённой, вызвав ошибку линковки (чтобы определить функцию с сообщением в разделе .gnu.warning*), при использовании этих атрибутов проблема диагностируется раньше и с точным местоположением вызова, даже при наличии встроенных функций или отсутствии отладочной информации.

externally_visible

Этот атрибут, прикреплённый к глобальной переменной или функции, аннулирует действие параметра командной строки -fwhole-program, поэтому объект остаётся видимым за пределами текущей единицы компиляции.

Если -fwhole-program используется вместе с -flto и gold используется в качестве плагина компоновщика, атрибуты externally_visible автоматически добавляются к функциям (а не к переменным пока, из-за текущей проблемы gold), к которым осуществляется доступ за пределами объектов LTO в соответствии с файлом разрешения, созданным gold. Для других компоновщиков, которые не могут сгенерировать файл разрешения, явные атрибуты externally_visible по-прежнему необходимы.

flatten

В целом, инлайнинг в функцию ограничен. Для функции, помеченной этим атрибутом, каждый вызов внутри этой функции выполняется в инлайне, если это возможно. Функции, объявленные с атрибутом noinline и аналогичные, не инлайнируются. Будет ли сама функция рассматриваться для инлайнинга, зависит от её размера и текущих параметров инлайнинга.

format (archetype, string-index, first-to-check)

Атрибут format указывает, что функция принимает аргументы printf, scanf, strftime или strfmon стиля, которые должны быть проверены на соответствие строке формата. Например, объявление:

extern int
my_printf (void *my_object, const char *my_format, ...)
      __attribute__ ((format (printf, 2, 3)));

приводит к тому, что компилятор проверяет аргументы в вызовах функции my_printf на соответствие строке формата стиля printf аргумента my_format.

Параметр archetype определяет, как интерпретируется строка формата, и должен быть printf, scanf, strftime, gnu_printf, gnu_scanf, gnu_strftime или strfmon. (Также можно использовать __printf__, __scanf__, __strftime__ или __strfmon__.) На целевых платформах MinGW также присутствуют ms_printf, ms_scanf и ms_strftime. Значения archetype, такие как printf, относятся к форматам, поддерживаемым системной библиотекой времени выполнения C, а значения, начинающиеся с ‘gnu_’, всегда относятся к форматам, поддерживаемым GNU C Library. На целевых платформах Microsoft Windows значения, начинающиеся с ‘ms_’, относятся к форматам, поддерживаемым библиотекой msvcrt.dll. Параметр string-index указывает, какой аргумент является аргументом строки формата (начиная с 1), а first-to-check — номер первого аргумента для проверки по отношению к строке формата. Для функций, где аргументы недоступны для проверки (например, vprintf ), укажите третий параметр как ноль. В этом случае компилятор проверяет только строку формата на соответствие. Для форматов strftime третий параметр должен быть равен нулю. Поскольку у нестатических методов C++ есть неявный аргумент this, аргументы таких методов должны учитываться с позиции два, а не один, при указании значений для string-index и first-to-check.

В приведённом примере строка формата (my_format) является вторым аргументом функции my_print, а аргументы для проверки начинаются с третьего аргумента, поэтому правильные параметры для атрибута формата — 2 и 3.

Атрибут format позволяет идентифицировать собственные функции, которые принимают строки формата в качестве аргументов, чтобы GCC мог проверять вызовы этих функций на ошибки. Компилятор всегда (если не используется -ffreestanding или -fno-builtin) проверяет форматы для стандартных функций библиотеки printf, fprintf, sprintf, scanf, fscanf, sscanf, strftime, vprintf, vfprintf и vsprintf, когда такие предупреждения запрошены (с использованием -Wformat), поэтому нет необходимости изменять заголовочный файл stdio.h. В режиме C99 также проверяются функции snprintf, vsnprintf, vscanf, vfscanf и vsscanf. За исключением строгого соответствия стандарту C, функция X/Open strfmon также проверяется, как и printf_unlocked и fprintf_unlocked. См. Параметры, контролирующие диалект C.

Для диалектов Objective-C распознаётся NSString (или __NSString__) в том же контексте. Объявления, включающие эти атрибуты формата, анализируются для правильного синтаксиса, однако результат проверки таких строк формата пока не определён и не выполняется этой версией компилятора.

Целевая платформа может также предоставлять дополнительные типы проверок форматов. См. Проверки форматов, специфичные для конкретных целевых платформ.

format_arg (string-index)

Атрибут format_arg указывает, что функция принимает одну или несколько строк формата для функций типа printf, scanf, strftime или strfmon и изменяет их (например, для перевода на другой язык), чтобы результат можно было передать функции типа printf, scanf, strftime или strfmon (при этом остальные аргументы функции формата остаются такими же, как и для немодифицированной строки). Один и тот же функции могут применяться несколько атрибутов format_arg, каждый из которых обозначает отдельный параметр в качестве строки формата. Например, объявление:

extern char *
my_dgettext (char *my_domain, const char *my_format)
      __attribute__ ((format_arg (2)));

приводит к тому, что компилятор проверяет аргументы в вызовах функции типа printf, scanf, strftime или strfmon, в которой аргументом строки формата является вызов функции my_dgettext, на соответствие аргументу строки формата my_format. Если бы не был указан атрибут format_arg, компилятор мог бы определить только то, что аргумент строки формата не является константой; это вызвало бы предупреждение при использовании -Wformat-nonliteral, но вызовы не могли бы быть проверены без этого атрибута.

При вызовах функции, объявленной с более чем одним атрибутом format_arg, каждый со своим значением аргумента, соответствующие фактические аргументы функции проверяются на соответствие всем строкам формата, обозначенным атрибутами. Эта возможность предназначена для поддержки семейства функций GNU ngettext.

Параметр string-index указывает, какой аргумент является аргументом строки формата (начиная с одного). Поскольку у нестатических методов C++ есть неявный аргумент this, аргументы таких методов должны учитываться с позиции два.

Атрибут format_arg позволяет идентифицировать собственные функции, которые изменяют строки формата, чтобы GCC мог проверять вызовы функций типа printf, scanf, strftime или strfmon, в которых операндами являются вызовы одной из собственных функций. Компилятор всегда обрабатывает gettext, dgettext, и dcgettext таким образом, за исключением случаев, когда поддержка строгого стандарта ISO C запрошена с помощью -ansi или соответствующего параметра -std, или когда используется -ffreestanding или -fno-builtin. См. Параметры, контролирующие диалект C.

Для диалектов Objective-C атрибут format-arg может ссылаться на NSString ссылку для совместимости с атрибутом format выше.

Целевая платформа может также разрешать дополнительные типы в атрибутах format-arg. См. Проверки форматов, специфичные для конкретных целевых платформ.

gnu_inline

Этот атрибут следует использовать с функцией, которая также объявлена с ключевым словом inline. Он указывает GCC на то, что функция должна обрабатываться как если бы она была определена в режиме gnu90, даже при компиляции в режиме C99 или gnu99.

Если функция объявлена как extern, тогда это определение функции используется только для инлайнинга. Ни в коем случае функция не компилируется как отдельная функция, даже если вы явно берёте её адрес. Такой адрес становится внешней ссылкой, как если бы вы только объявили функцию, но не определили её. Это почти эквивалентно макросу. Способ использования — разместить определение функции в заголовочном файле с этим атрибутом и поместить другую копию функции без extern в файле библиотеки. Определение в заголовочном файле приводит к инлайнингу большинства вызовов функции. Если какие-либо вызовы функции остаются, они ссылаются на единственную копию в библиотеке. Обратите внимание, что два определения функций могут отличаться, хотя если они не имеют одинакового эффекта, ваше приложение может вести себя странно.

В C, если функция не extern и не static, она компилируется как отдельная функция, а также инлайнится, где это возможно.

Это то, как GCC традиционно обрабатывал функции, объявленные как inline. Поскольку ISO C99 определяет другую семантику для inline, этот атрибут функции предоставляется как переходная мера и как полезная функция сама по себе. Этот атрибут доступен в GCC 4.1.3 и более поздних версиях. Он доступен, если определены либо препроцессорные макросы __GNUC_GNU_INLINE__ или __GNUC_STDC_INLINE__. См. Функция инлайна — так же быстра, как макрос.

В C++, этот атрибут никак не зависит от extern, но всё ещё требует ключевого слова inline, чтобы включить своё особое поведение.

hot

Атрибут hot для функции используется для информирования компилятора о том, что функция является горячей точкой компилируемой программы. Функция оптимизируется более агрессивно, и на многих целевых платформах она помещается в специальный подсекцию секции текста, так что все горячие функции находятся близко друг к другу, улучшая локальность.

Когда доступна обратная связь профилирования, через -fprofile-use, горячие функции автоматически обнаруживаются, и этот атрибут игнорируется.

ifunc ("resolver")

Атрибут ifunc используется для маркировки функции как косвенной, используя расширение типа символа STT_GNU_IFUNC к стандарту ELF. Это позволяет динамически определить значение символа во время загрузки и выбрать оптимизированную версию процедуры для конкретного процессора или других характеристик системы, определяемых тогда. Для использования этого атрибута сначала нужно определить доступные функции реализации и функцию-разрешитель, возвращающую указатель на выбранную функцию реализации. Объявления функций реализации должны соответствовать API реализуемой функции. Разрешитель должен быть объявлен как функция без аргументов, возвращающая указатель на функцию того же типа, что и функция реализации. Например:

void *my_memcpy (void *dst, const void *src, size_t len)
{
  …
  return dst;
}

static void * (*resolve_memcpy (void))(void *, const void *, size_t)
{
  return my_memcpy; // we will just always select this routine
}

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

extern void *memcpy (void *, const void *, size_t);

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

void *memcpy (void *, const void *, size_t)
     __attribute__ ((ifunc ("resolve_memcpy")));

В C++, атрибут ifunc принимает строку, которая является искажённым именем функции-разрешителя. Функция-разрешитель C++ для нестатического метода класса C должна быть объявлена так, чтобы возвращать указатель на функцию, не являющуюся методом, принимающую указатель на C в качестве первого аргумента, а затем те же аргументы, что и функция реализации. G++ проверяет сигнатуры обеих функций и выдает предупреждение -Wattribute-alias при несоответствиях. Чтобы подавить предупреждение о необходимости преобразования типа указателя на член-функцию реализации в тип соответствующей функции, не являющейся методом, используйте опцию -Wno-pmf-conversions. Например:

class S
{
private:
  int debug_impl (int);
  int optimized_impl (int);

  typedef int Func (S*, int);

  static Func* resolver ();
public:

  int interface (int);
};

int S::debug_impl (int) { /* … */ }
int S::optimized_impl (int) { /* … */ }

S::Func* S::resolver ()
{
  int (S::*pimpl) (int)
    = getenv ("DEBUG") ? &S::debug_impl : &S::optimized_impl;

  // Cast triggers -Wno-pmf-conversions.
  return reinterpret_cast<Func*>(pimpl);
}

int S::interface (int) __attribute__ ((ifunc ("_ZN1S8resolverEv")));

Косвенные функции не могут быть слабыми. Для использования этой функции требуется версия Binutils 2.20.1 или выше и GNU C Library 2.11.1 или выше.

interrupt
interrupt_handler

Многие бэкэнды GCC поддерживают атрибуты, указывающие, что функция является обработчиком прерывания, что сообщает компилятору сгенерировать последовательности входа и выхода из функции, отличающиеся от последовательностей обычных функций. Точный синтаксис и поведение зависят от целевой платформы; см. соответствующие разделы для получения подробностей.

leaf

Вызовы внешних функций с этим атрибутом должны возвращаться в текущий модуль компиляции только через возврат или обработку исключений. В частности, функция-листок не может вызывать функции обратного вызова, переданные ей из текущего модуля компиляции, непосредственно вызывать экспортированные функциями модуля или longjmp в модуль. Функции-листки всё ещё могут вызывать функции из других модулей компиляции и, таким образом, они не обязательно являются листками в том смысле, что не содержат никаких вызовов функций вообще.

Атрибут предназначен для функций библиотек, чтобы улучшить анализ потока данных. Компилятор принимает указание о том, что любые данные, не выходящие за пределы текущего модуля компиляции, не могут использоваться или изменяться функцией-листком. Например, функция sin является функцией-листком, но qsort ею не является.

Обратите внимание, что функции-листки могут косвенно запускать обработчик сигнала, определённый в текущем модуле компиляции, использующий статические переменные. Аналогично, при отложенном разрешении символов, функции-листки могут вызывать косвенные функции, функции-разрешители или функции реализации которых определены в текущем модуле компиляции и используют статические переменные. Нет стандартного способа написать такой обработчик сигнала, функцию-разрешителя или функцию реализации, и всё, что вы можете сделать, это удалить атрибут leaf или пометить все такие статические переменные volatile. Наконец, для систем на основе ELF, поддерживающих интерпозицию символов, следует позаботиться о том, чтобы функции, определённые в текущем модуле компиляции, не предсказуемо интерпонировали другие символы, основанные на определённом режиме стандарта и определённых макросах тестов функций; в противном случае будет добавлен нежелательный обратный вызов.

Атрибут не влияет на функции, определённые в текущем модуле компиляции. Это позволяет легко объединять несколько модулей компиляции в один, например, с помощью оптимизации на этапе компоновки. По этой причине атрибут не разрешается для типов для аннотирования косвенных вызовов.

malloc
malloc (deallocator)
malloc (deallocator, ptr-index)

Атрибут malloc указывает, что функция является похожей на malloc, т. е. что указатель P, возвращаемый функцией, не может ссылаться на какой-либо другой указатель, действительный при возврате функции, а также никакие указатели на действительные объекты не встречаются в любом хранилище, адресуемом P. Кроме того, GCC предполагает, что функция с этим атрибутом возвращает не нуль в большинстве случаев.

Независимо от этого, форма атрибута с одним или двумя аргументами связывает deallocator как подходящую функцию освобождения для указателей, возвращаемых из функции, похожей на malloc. ptr-index обозначает позиционный аргумент, при передаче которого указатель в вызовы deallocator вызывает его освобождение.

Использование атрибута без аргументов предназначено для улучшения оптимизации, полагаясь на свойство алиасинга, которое оно подразумевает. Функции, такие как malloc и calloc, обладают этим свойством, потому что они возвращают указатель на неинициализированное или обнулённое, недавно полученное хранилище. Однако функции, такие как realloc, не обладают этим свойством, так как они могут возвращать указатели на хранилище, содержащее указатели на существующие объекты. Кроме того, так как предполагается, что все такие функции возвращают ноль только нечасто, вызывающие функции могут быть оптимизированы на основе этого предположения.

Связывание функции с deallocator помогает выявить вызовы несоответствующих функций выделения и освобождения и диагностировать их под управлением таких опций, как -Wmismatched-dealloc. Это также позволяет диагностировать попытки освободить объекты, которые не были динамически выделены, с помощью -Wfree-nonheap-object. Для указания того, что функция выделения удовлетворяет свойству неалиасинга и имеет связанную с ней функцию освобождения, необходимо использовать как простую форму атрибута, так и форму с аргументом deallocator. Одна и та же функция может быть и функцией выделения, и функцией освобождения. Поскольку встраивание одной из связанных функций, но не другой, может привести к видимым несоответствиям, эта форма атрибута malloc не принимается для встроенных функций. По той же причине использование атрибута предотвращает как функции выделения, так и функции освобождения от расширения встраивания.

Например, помимо того, что функции возвращают указатели, которые не ссылаются на другие, следующие объявления делают fclose подходящей функцией освобождения для указателей, возвращаемых из всех функций, кроме popen, и pclose единственной подходящей функцией освобождения для указателей, возвращаемых из popen. Функции освобождения должны быть объявлены перед тем, как к ним можно будет обратиться в атрибуте.

int fclose (FILE*);
int pclose (FILE*);

__attribute__ ((malloc, malloc (fclose, 1)))
  FILE* fdopen (int, const char*);
__attribute__ ((malloc, malloc (fclose, 1)))
  FILE* fopen (const char*, const char*);
__attribute__ ((malloc, malloc (fclose, 1)))
  FILE* fmemopen(void *, size_t, const char *);
__attribute__ ((malloc, malloc (pclose, 1)))
  FILE* popen (const char*, const char*);
__attribute__ ((malloc, malloc (fclose, 1)))
  FILE* tmpfile (void);

Предупреждения, защищенные -fanalyzer, учитывают пары выделения и освобождения, помеченные malloc. В частности:

  • Анализатор выдаст диагностическое сообщение -Wanalyzer-mismatching-deallocation, если существует путь выполнения, в котором результат вызова выделения передаётся другому освободителю.
  • Анализатор выдаст диагностическое сообщение -Wanalyzer-double-free, если существует путь выполнения, в котором значение передаётся более одного раза для освобождения.
  • Анализатор учтёт возможность того, что функция выделения может завершиться неудачно и вернуть NULL. Он выдаст диагностические сообщения -Wanalyzer-possible-null-dereference и -Wanalyzer-possible-null-argument, если существуют пути выполнения, в которых не проверенный результат вызова выделения используется или передаётся в функцию, требующую не нулевого аргумента. Если функция выделения всегда возвращает не нуль, используйте __attribute__ ((returns_nonnull)) для подавления этих предупреждений. Например:
    char *xstrdup (const char *)
      __attribute__((malloc (free), returns_nonnull));
  • Анализатор выдаст диагностическое сообщение -Wanalyzer-use-after-free, если существует путь выполнения, в котором память, переданная указателем в вызов освобождения, используется после освобождения.
  • Анализатор выдаст диагностическое сообщение -Wanalyzer-malloc-leak, если существует путь выполнения, в котором результат вызова выделения утекает (не передаётся функции освобождения).
  • Анализатор выдаст диагностическое сообщение -Wanalyzer-free-of-non-heap, если функция освобождения используется для глобальной или стековой переменной.

Анализатор предполагает, что функции освобождения могут корректно обработать указатель NULL. Если это не так, функция освобождения может быть помечена __attribute__((nonnull)), чтобы -fanalyzer мог выдать диагностическое сообщение -Wanalyzer-possible-null-argument для путей кода, в которых функция освобождения вызывается с NULL.

no_icf

Этот атрибут функции предотвращает объединение функций с другой семантически эквивалентной функцией.

no_instrument_function

Если заданы -finstrument-functions, -p или -pg, генерируются функции профилирования вызовов функций в начале и конце большинства функций, скомпилированных пользователем. Функции с этим атрибутом не инструментируются таким образом.

no_profile_instrument_function

Атрибут no_profile_instrument_function для функций используется для того, чтобы сообщить компилятору, что он не должен обрабатывать любые оптимизации кода на основе обратной связи профиля.

no_reorder

Не переупорядочивать функции или переменные, помеченные no_reorder, по отношению друг к другу или к верхним уровням инструкций ассемблера в исполняемом файле. Фактический порядок в программе будет зависеть от командной строки компоновщика. Статические переменные, помеченные таким образом, также не удаляются. Это имеет аналогичный эффект, как опция -fno-toplevel-reorder, но применяется только к помеченным символам.

no_sanitize ("sanitize_option")

Атрибут no_sanitize для функций используется для того, чтобы сообщить компилятору, что он не должен выполнять проверку на ошибки для любой опции, упомянутой в sanitize_option. Список допустимых значений для опции -fsanitize может быть предоставлен.

void __attribute__ ((no_sanitize ("alignment", "object-size")))
f () { /* Do something. */; }
void __attribute__ ((no_sanitize ("alignment,object-size")))
g () { /* Do something. */; }
no_sanitize_address
no_address_safety_analysis

Атрибут no_sanitize_address для функций используется для того, чтобы сообщить компилятору, что он не должен инструментировать обращения к памяти в функции при компиляции с опцией -fsanitize=address. Атрибут no_address_safety_analysis является устаревшим алиасом атрибута no_sanitize_address, новый код должен использовать no_sanitize_address.

no_sanitize_thread

Атрибут no_sanitize_thread для функций используется для того, чтобы сообщить компилятору, что он не должен инструментировать обращения к памяти в функции при компиляции с опцией -fsanitize=thread.

no_sanitize_undefined

Атрибут no_sanitize_undefined для функций используется для того, чтобы сообщить компилятору, что он не должен проверять неопределённое поведение в функции при компиляции с опцией -fsanitize=undefined.

no_sanitize_coverage

Атрибут no_sanitize_coverage для функций используется для того, чтобы сообщить компилятору, что он не должен выполнять инструментирование кода для fuzzing с учётом покрытия (-fsanitize-coverage).

no_split_stack

Если задана опция -fsplit-stack, функции имеют небольшой пролог, который определяет, нужно ли разделять стек. Функции с атрибутом no_split_stack не имеют этого пролога и, следовательно, могут выполняться только с небольшим объёмом доступной памяти стека.

no_stack_limit

Этот атрибут локально переопределяет опции командной строки -fstack-limit-register и -fstack-limit-symbol; он имеет эффект отключения проверки лимита стека в функции, к которой он применяется.

noclone

Этот атрибут функции предотвращает рассмотрение функции для клонирования — механизма, создающего специализированные копии функций, который (в настоящее время) выполняется посредством межпроцедурной константной подстановки.

noinline

Этот атрибут функции предотвращает рассмотрение функции для встраивания. Если функция не имеет побочных эффектов, существуют оптимизации, помимо встраивания, которые приводят к оптимизации вызовов функций, хотя вызов функции активен. Чтобы предотвратить оптимизацию таких вызовов, поместите

asm ("");

(см. Расширенное ассемблерное программирование) в вызываемой функции, чтобы служить специальным побочным эффектом.

noipa

Отключить межпроцедурные оптимизации между функцией с этим атрибутом и её вызывающими функциями, как если бы тело функции было недоступно при оптимизации вызывающих функций, а вызывающие функции — недоступны при оптимизации тела. Этот атрибут подразумевает атрибуты noinline, noclone и no_icf. Однако этот атрибут не эквивалентен комбинации других атрибутов, потому что его цель состоит в подавлении существующих и будущих оптимизаций, использующих межпроцедурный анализ, включая те, у которых нет атрибута, подходящего для их отключения индивидуально. Этот атрибут поддерживается в основном для целей тестирования компилятора.

nonnull
nonnull (arg-index, …)

Атрибут nonnull может быть применён к функции, которая принимает по крайней мере один аргумент типа указателя. Он указывает, что указанные аргументы должны быть указателями, не равными нулю. Например, объявление:

extern void *
my_memcpy (void *dest, const void *src, size_t len)
        __attribute__((nonnull (1, 2)));

сообщает компилятору, что в вызовах my_memcpy, аргументы dest и src должны быть указателями, не равными нулю.

Атрибут оказывает влияние как на вызовы функций, так и на определения функций.

Для вызовов функций:

  • Если компилятор определяет, что в аргумент, помеченный как «не нулевой», передаётся нулевой указатель, и опция -Wnonnull включена, выдаётся предупреждение. См. Опции предупреждений.
  • Опция -fisolate-erroneous-paths-attribute может быть указана для преобразования компилятором вызовов с нулевыми аргументами в функции, помеченные как «не нулевые», в ловушки. См. Опции оптимизации.
  • Компилятор также может выполнять оптимизации, основываясь на знании, что некоторые аргументы функций не могут быть нулевыми. Эти оптимизации могут быть отключены опцией -fno-delete-null-pointer-checks. См. Опции оптимизации.

Для определений функций:

  • Если компилятор определяет, что параметр функции, помеченный как nonnull, сравнивается с нулём, и опция -Wnonnull-compare включена, выдаётся предупреждение. См. Опции предупреждений.
  • Компилятор также может выполнять оптимизации на основе знания, что параметры nonnul не могут быть нулевыми. В настоящее время это нельзя отключить, кроме как удалив атрибут nonnull.

Если атрибуту nonnull не указан arg-index, все аргументы-указатели отмечаются как «не нулевые». Для иллюстрации, следующее объявление эквивалентно предыдущему примеру:

extern void *
my_memcpy (void *dest, const void *src, size_t len)
        __attribute__((nonnull));
noplt

Атрибут noplt является аналогом опции -fno-plt. Вызовы функций, помеченных этим атрибутом в позиционно-независимом коде, не используют PLT.

/* Externally defined function foo.  */
int foo () __attribute__ ((noplt));

int
main (/* … */)
{
  /* … */
  foo ();
  /* … */
}

Атрибут noplt на функции foo сообщает компилятору, что функция foo определена внешне и что вызов foo должен обойти PLT в позиционно-независимом коде.

В позиционно-зависимом коде некоторые целевые платформы также преобразуют вызовы функций, помеченных как не использующие PLT, в использование GOT вместо него.

noreturn

Некоторые функции стандартной библиотеки, такие как abort и exit, не могут вернуть значение. GCC автоматически знает об этом. Некоторые программы определяют собственные функции, которые никогда не возвращают значение. Вы можете объявить их как noreturn для того, чтобы сообщить об этом компилятору. Например,

void fatal () __attribute__ ((noreturn));

void
fatal (/* … */)
{
  /* … */ /* Print error message. */ /* … */
  exit (1);
}

Ключевое слово noreturn сообщает компилятору, что функция fatal не может вернуть значение. Затем он может оптимизировать, не учитывая то, что произойдёт, если функция fatal когда-либо вернётся. Это улучшает код.

Более важно, это помогает избежать ложных предупреждений об инициализированных переменных.

Ключевое слово noreturn не влияет на исключительные ситуации, когда они применяются: функция, помеченная как noreturn, по-прежнему может вернуться к вызывающей функции, выбросив исключение или вызвав longjmp.

Для сохранения стека отслеживания ошибок GCC никогда не преобразует вызовы функций, помеченных как noreturn, в хвостовые вызовы.

Не предполагайте, что регистры, сохранённые вызывающей функцией, восстанавливаются до вызова функции noreturn.

Не имеет смысла, чтобы функция noreturn имела тип возвращаемого значения, отличный от void.

nothrow

Атрибут nothrow используется для информирования компилятора о том, что функция не может выбросить исключение. Например, большинство функций в стандартной библиотеке C гарантированно не выбросят исключение, за исключением qsort и bsearch , которые принимают указатели на функции.

optimize (level, …)
optimize (string, …)

Атрибут optimize используется для указания того, что функция должна компилироваться с различными параметрами оптимизации, чем заданные в командной строке. Аргументы атрибута optimize функции ведут себя так, как будто они добавлены в командную строку.

Допустимые аргументы — это константы неотрицательные целые числа и строки. Каждый числовой аргумент задаёт уровень оптимизации level. Каждая строка string состоит из одной или нескольких подстрок, разделённых запятыми. Каждая подстрока, начинающаяся с буквы O, относится к параметру оптимизации, например -O0 или -Os. Другие подстроки рассматриваются как суффиксы префикса -f вместе, образуя имя параметра оптимизации. См. Опции оптимизации.

‘#pragma GCC optimize’ можно использовать для задания параметров оптимизации для более чем одной функции. См. Параметры функций для опций для получения дополнительных сведений о директиве.

Указание нескольких строк в качестве аргументов, разделённых запятыми, для задания нескольких параметров, эквивалентно разделению суффиксов параметров запятыми («,») в одной строке. Пробелы внутри строк недопустимы.

Не каждый параметр оптимизации, начинающийся с префикса -f и указанный атрибутом, обязательно оказывает влияние на функцию. Атрибут optimize следует использовать только в отладочных целях. Он не подходит для кода, используемого в рабочей среде.

patchable_function_entry

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

Атрибут функции patchable_function_entry может быть использован для изменения количества NOP-инструкций на любое желаемое значение. Двухзначный синтаксис такой же, как для переключателя командной строки -fpatchable-function-entry=N,M, генерирующего N NOP-инструкций, с точкой входа в функцию перед M-й NOP-инструкцией. M по умолчанию равно 0, если не указано, например, точка входа в функцию находится перед первой NOP-инструкцией.

Если включение функций с изменяемыми входами включено глобально с помощью опции командной строки -fpatchable-function-entry=N,M, необходимо отключить инструментирование для всех функций, которые являются частью фреймворка инструментирования, с помощью атрибута patchable_function_entry (0) для предотвращения рекурсии.

pure

Обращения к функциям, не оказывающим наблюдаемого влияния на состояние программы, кроме возвращения значения, могут быть оптимизированы, например, путём устранения общих подвыражений. Объявление таких функций с атрибутом pure позволяет GCC избегать вызова функции при повторных вызовах с одинаковыми аргументами.

Атрибут pure запрещает функции изменять состояние программы, которое может быть наблюдаемо другими средствами, кроме проверки значения возврата функции. Однако функции, объявленные с атрибутом pure , могут безопасно считывать любые не-volatile объекты и изменять значение объектов таким образом, что это не повлияет на их возвращаемое значение или наблюдаемое состояние программы.

Например,

int hash (char *) __attribute__ ((pure));

указывает GCC, что последующие вызовы функции hash с той же строкой могут быть заменены результатом первого вызова, при условии, что состояние программы, наблюдаемое hash, включая содержимое массива, не изменяется между вызовами. Несмотря на то, что hash принимает аргумент указателя на не-const, она не должна изменять массив, на который указывает, или любой другой объект, значение которого может зависеть от остальной части программы. Однако вызывающая функция может безопасно изменять содержимое массива между последовательными вызовами функции (это отключает оптимизацию). Ограничение также применяется к объектам-членам, на которые ссылается указатель this в нестатических членских функциях C++.

Некоторые общие примеры чистых функций — strlen или memcmp. Интересными нечистыми функциями являются функции с бесконечными циклами или функции, зависящие от volatile памяти или других системных ресурсов, которые могут изменяться между последовательными вызовами (например, стандартная C-функция feof в многопоточной среде).

Атрибут pure накладывает аналогичные, но более слабые ограничения на определение функции, чем атрибут const: pure разрешает функции считывать любую не-volatile память, даже если она изменяется между последовательными вызовами. Объявление одной и той же функции с атрибутами pure и const приводит к диагностике. Так как чистая функция не может иметь каких-либо наблюдаемых побочных эффектов, не имеет смысла, чтобы такая функция возвращала void. Объявление такой функции приводит к диагностике.

returns_nonnull

Атрибут returns_nonnull указывает, что значение возврата функции должно быть указателем на не-null. Например, объявление:

extern void *
mymalloc (size_t len) __attribute__((returns_nonnull));

позволяет компилятору оптимизировать вызывающие функции, зная, что возвращаемое значение никогда не будет null.

returns_twice

Атрибут returns_twice сообщает компилятору, что функция может возвращать значение более одного раза. Компилятор гарантирует, что все регистры являются мёртвыми перед вызовом такой функции, и выводит предупреждение о переменных, которые могут быть испорчены после второго возврата из функции. Примеры таких функций — setjmp и vfork. Соответствующая функция, аналогичная longjmp, если она есть, может потребовать метки с атрибутом noreturn.

section ("section-name")

Обычно компилятор размещает сгенерированный код в секции text. Иногда, однако, вам нужны дополнительные секции или вам нужно, чтобы определённые функции появлялись в специальных секциях. Атрибут section указывает, что функция находится в конкретной секции. Например, объявление:

extern void foobar (void) __attribute__ ((section ("bar")));

размещает функцию foobar в секции bar.

Некоторые форматы файлов не поддерживают произвольные секции, поэтому атрибут section недоступен на всех платформах. Если вам нужно отобразить всё содержимое модуля в конкретную секцию, воспользуйтесь возможностями компоновщика.

sentinel
sentinel (position)

Этот атрибут функции указывает, что аргумент в вызове функции ожидается как явный NULL . Атрибут действителен только для функций с переменным числом аргументов. По умолчанию сигнальный элемент ожидается как последний аргумент вызова функции. Если необязательный аргумент position указан в атрибуте, сигнальный элемент должен находиться в позиции position, отсчитываемой от конца списка аргументов.

__attribute__ ((sentinel))
is equivalent to
__attribute__ ((sentinel(0)))

Атрибут автоматически устанавливается с позицией 0 для встроенных функций execl и execlp . Встроенная функция execle имеет атрибут, установленный с позицией 1.

Допустимый NULL в данном контексте определяется как ноль с типом указателя на любой объект. Если ваша система определяет макрос NULL с целочисленным типом, вам необходимо добавить явное приведение типов. Во время установки GCC заменяет системный заголовок <stddef.h> копией, которая соответствующим образом переопределяет NULL.

Предупреждения о пропущенных или неправильных сигнальных элементах включаются с -Wformat.

simd
simd("mask")

Этот атрибут позволяет создать одну или несколько версий функций, которые могут обрабатывать несколько аргументов с помощью инструкций SIMD из одного вызова. Указание этого атрибута позволяет компилятору предположить, что такие версии доступны во время компоновки (приведены в том же или другом единице трансляции). Сгенерированные версии зависят от целевой платформы и описаны в соответствующем документе Vector ABI. Для целевой платформы x86_64 этот документ можно найти здесь.

Необязательный аргумент mask может принимать значение notinbranch или inbranch, и соответственно инструктирует компилятор сгенерировать не-маскированные или маскированные копии. По умолчанию генерируются все копии.

Если атрибут указан, и #pragma omp declare simd присутствует в объявлении, а ключ -fopenmp или -fopenmp-simd указаны, то атрибут игнорируется.

stack_protect

Этот атрибут добавляет код защиты стека к функции, если установлены флаги -fstack-protector, -fstack-protector-strong или -fstack-protector-explicit.

no_stack_protector

Этот атрибут предотвращает код защиты стека для функции.

target (string, …)

Несколько целевых бэкендов реализуют атрибут target , чтобы указать, что функция должна компилироваться с различными целевыми параметрами, чем указано в командной строке. Исходные целевые параметры командной строки игнорируются. В качестве аргументов можно передать одну или несколько строк. Каждая строка состоит из одного или нескольких параметров, разделённых запятыми, которые в совокупности образуют имя платформозависимого параметра с префиксом -m . См. Параметры платформы.

Например, атрибут target может быть использован для компиляции функции с другим ISA (архитектурой набора команд), чем по умолчанию. '#pragma GCC target' можно использовать для указания целевых параметров для более чем одной функции. См. Параметры, специфичные для функции, для получения подробной информации о препроцессорной директиве.

Например, в x86 можно объявить одну функцию с атрибутом target("sse4.1,arch=core2") и другую с атрибутом target("sse4a,arch=amdfam10"). Это эквивалентно компиляции первой функции с параметрами -msse4.1 и -march=core2, а второй функции с параметрами -msse4a и -march=amdfam10. Вам необходимо убедиться, что функция вызывается только на машине, которая поддерживает конкретный ISA, для которого она скомпилирована (например, используя cpuid в x86 для определения используемых битов функций и семейства архитектуры).

int core2_func (void) __attribute__ ((__target__ ("arch=core2")));
int sse3_func (void) __attribute__ ((__target__ ("sse3")));

Передача нескольких строк в качестве аргументов, разделённых запятыми, для указания нескольких параметров, эквивалентна разделению суффиксов параметров запятой (',' ) в одной строке. Пробелы внутри строк запрещены.

Поддерживаемые параметры зависят от каждой целевой платформы; обратитесь к Атрибуты функций x86, Атрибуты функций PowerPC, Атрибуты функций ARM, Атрибуты функций AArch64, Атрибуты функций Nios II и Атрибуты функций S/390 для получения подробной информации.

symver ("name2@nodename")

В целевых платформах ELF этот атрибут создаёт версию символа. Часть name2 параметра — фактическое имя символа, по которому на него будет ссылаться внешне. Часть nodename должна содержать имя узла, указанного в скрипте версии, предоставленном компоновщику при построении динамической библиотеки. Версионированный символ должен быть определён и должен экспортироваться с видимость по умолчанию.

__attribute__ ((__symver__ ("foo@VERS_1"))) int
foo_v1 (void)
{
}

Создаст директиву .symver foo_v1, foo@VERS_1 в выходных данных ассемблера.

Можно также определить несколько версий для данного символа (начиная с binutils 2.35).

__attribute__ ((__symver__ ("foo@VERS_2"), __symver__ ("foo@VERS_3")))
int symver_foo_v1 (void)
{
}

Этот пример создаёт имя символа symver_foo_v1, который будет иметь версию VERS_2 и VERS_3 символа foo.

Если у вас более старая версия binutils, то необходимо использовать алиас символа:

__attribute__ ((__symver__ ("foo@VERS_2")))
int foo_v1 (void)
{
  return 0;
}

__attribute__ ((__symver__ ("foo@VERS_3")))
__attribute__ ((alias ("foo_v1")))
int symver_foo_v1 (void);

Наконец, если параметр является "name2@@nodename", то помимо создания версии символа (как если бы использовался "name2@nodename" ), версия также будет использоваться для разрешения name2 компоновщиком.

tainted_args

Атрибут tainted_args используется для указания, что функция вызывается таким образом, что требует очистки ее аргументов, например, системный вызов в ядре операционной системы. Такую функцию можно считать частью «поверхности атаки» программы. Атрибут можно использовать как в объявлениях функций, так и в объявлениях полей, содержащих указатели на функции. В последнем случае любая функция, используемая в качестве инициализатора такого обратного вызова, будет обрабатываться как вызываемая с зараженными аргументами.

Анализатор уделит особое внимание таким функциям, когда указаны как -fanalyzer, так и -fanalyzer-checker=taint, потенциально вызывая предупреждения, защищенные -Wanalyzer-tainted-allocation-size, -Wanalyzer-tainted-array-index, -Wanalyzer-tainted-divisor, -Wanalyzer-tainted-offset и -Wanalyzer-tainted-size.

target_clones (options)

Атрибут target_clones используется для указания того, что функция будет клонирована в несколько версий, скомпилированных с различными целевыми параметрами, отличными от указанных в командной строке. Поддерживаемые параметры и ограничения такие же, как и для атрибута target.

Например, на x86 вы можете скомпилировать функцию с target_clones("sse4.1,avx"). GCC создаст два клона функций, один скомпилированный с -msse4.1, а другой с -mavx.

На PowerPC вы можете скомпилировать функцию с target_clones("cpu=power9,default"). GCC создаст два клона функций, один скомпилированный с -mcpu=power9, а другой с параметрами по умолчанию. GCC должен быть сконфигурирован для использования GLIBC 2.23 или более поздней версии, чтобы использовать атрибут target_clones.

Он также создает функцию-резольвер (см. атрибут ifunc выше), которая динамически выбирает клон, подходящий для текущей архитектуры. Резольвер создается только в случае использования функции с атрибутом target_clones.

Обратите внимание, что любой последующий вызов функции без атрибута target_clone из вызывающей функции с атрибутом target_clone не приведет к копированию (клонированию целевой функции) вызываемой функции. Если вы хотите принудительно обеспечить такое поведение, рекомендуем объявить вызывающую функцию с атрибутом flatten?

unused

Этот атрибут, прикрепленный к функции, означает, что функция, возможно, не используется. GCC не выдает предупреждение для этой функции.

used

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

При применении к члену-функции шаблона класса C++, атрибут также означает, что функция будет экземпляризована, если сам класс экземпляризован.

retain

Для ELF-целей, поддерживающих GNU или FreeBSD OSABI, этот атрибут сохранит функцию от сборки мусора линковщиком. Для поддержки этого поведения функции, не размещенные в определенных секциях (например, атрибутом section, или параметром -ffunction-sections), будут помещены в новые уникальные секции.

Эта дополнительная функциональность требует Binutils версии 2.36 или более поздней.

visibility ("visibility_type")

Этот атрибут влияет на связь объявления, к которому он прикреплен. Его можно применять к переменным (см. Общие атрибуты переменных) и типам (см. Общие атрибуты типов), а также к функциям.

Поддерживаются четыре значения visibility_type: default, hidden, protected или internal visibility.

void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }
int i __attribute__ ((visibility ("hidden")));

Возможные значения visibility_type соответствуют настройкам видимости в ELF gABI.

default

Значение видимости по умолчанию является обычным случаем для формата файла объекта. Это значение доступно для атрибута видимости для переопределения других параметров, которые могут изменить предполагаемую видимость сущностей.

В ELF, видимость по умолчанию означает, что объявление видно другим модулям и, в общих библиотеках, означает, что объявленная сущность может быть переопределена.

В Darwin, видимость по умолчанию означает, что объявление видно другим модулям.

Видимость по умолчанию соответствует «внешней связи» в языке.

hidden

Видимость hidden указывает, что объявленная сущность имеет новый вид связи, которую мы называем «скрытой связью». Два объявления объекта со скрытой связью относятся к одному объекту, если они находятся в одном общем объекте.

internal

Видимость internal похожа на видимость hidden, но с дополнительными семантиками, специфичными для процессора. Если не указано иное в psABI, GCC определяет внутреннюю видимость как означающую, что к функции никогда не обращаются из другого модуля. Сравните это со скрытыми функциями, которые, хотя и не могут быть напрямую упомянуты в других модулях, могут быть упомянуты косвенно через указатели на функции. Указывая, что к функции нельзя обратиться извне модуля, GCC может, например, опустить загрузку регистра PIC, поскольку известно, что вызывающая функция загрузила правильное значение.

protected

Видимость protected похожа на видимость по умолчанию, за исключением того, что она указывает, что ссылки внутри определяющего модуля привязаны к определению в этом модуле. То есть, объявленная сущность не может быть переопределена другим модулем.

Все видимости поддерживаются во многих, но не во всех, ELF-целях (поддерживаются, когда ассемблер поддерживает псевдооператор ‘.visibility’). Видимость по умолчанию поддерживается везде. Скрытая видимость поддерживается на Darwin-целях.

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

В C++, атрибут видимости применяется к типам, а также к функциям и объектам, потому что в C++ типы имеют связь. Класс не должен иметь большей видимости, чем типы нестатических данных члена и базовые классы, а члены класса по умолчанию имеют видимость своего класса. Также объявление без явной видимости ограничено видимостью его типа.

В C++, вы можете отметить члены-функции и статические члены-переменные класса атрибутом видимости. Это полезно, если вам известно, что определенный метод или статическая переменная члена должны использоваться только из одного общего объекта; тогда вы можете отметить его скрытым, в то время как остальная часть класса имеет видимость по умолчанию. Следует быть внимательными, чтобы не нарушать правило единого определения; например, обычно не имеет смысла отмечать встроенный метод как скрытый, не отметив весь класс как скрытый.

Объявление пространства имен C++ также может иметь атрибут видимости.

namespace nspace1 __attribute__ ((visibility ("protected")))
{ /* Do something. */; }

Этот атрибут применяется только к определенному телу пространства имен, а не к другим определениям того же пространства имен; он эквивалентен использованию ‘#pragma GCC visibility’ до и после определения пространства имен (см. Атрибуты видимости).

В C++, если аргумент шаблона имеет ограниченную видимость, это ограничение подразумевается для экземпляризации шаблона. В противном случае экземпляризации и специализации шаблонов по умолчанию имеют видимость своего шаблона.

Если у шаблона и окружающего класса есть явная видимость, используется видимость от шаблона.

warn_unused_result

Атрибут warn_unused_result вызывает предупреждение, если вызывающая функция с этим атрибутом не использует возвращаемое значение. Это полезно для функций, где проверка результата является либо проблемой безопасности, либо всегда ошибкой, например, realloc.

int fn () __attribute__ ((warn_unused_result));
int foo ()
{
  if (fn () < 0) return -1;
  fn ();
  return 0;
}

приводит к предупреждению на строке 5.

weak

Атрибут weak вызывает объявление внешнего символа, которое выводится как слабый символ вместо глобального. Это в первую очередь полезно для определения функций библиотеки, которые могут быть переопределены в пользовательском коде, хотя его также можно использовать с объявлениями, отличными от функций. Переопределяющий символ должен иметь тот же тип, что и слабый символ. Кроме того, если он обозначает переменную, он также должен иметь тот же размер и выравнивание, что и слабый символ. Слабые символы поддерживаются для ELF-целей, а также для a.out-целей при использовании GNU-ассемблера и линковщика.

weakref
weakref ("target")

Атрибут weakref помечает объявление как слабую ссылку. Без аргументов его следует сопровождать атрибутом alias, указывающим целевой символ. В качестве альтернативы, target может быть передан как аргумент атрибуту weakref, называя целевое определение псевдонима. target должен иметь тот же тип, что и объявление. Кроме того, если он обозначает переменную, он также должен иметь тот же размер и выравнивание, что и объявление. В любом виде объявления weakref неявно помечает объявленный символ как weak. Без target, переданного в качестве аргумента weakref или alias, weakref эквивалентно weak (в этом случае объявление может быть extern).

/* Given the declaration: */
extern int y (void);

/* the following... */
static int x (void) __attribute__ ((weakref ("y")));

/* is equivalent to... */
static int x (void) __attribute__ ((weakref, alias ("y")));

/* or, alternatively, to... */
static int x (void) __attribute__ ((weakref));
static int x (void) __attribute__ ((alias ("y")));

Слабая ссылка — это псевдоним, который сам по себе не требует определения целевого символа. Если целевой символ ссылается только через слабые ссылки, то он становится неопределенным символом weak. Однако, если он непосредственно ссылается, то такие сильные ссылки имеют преимущество, и требуется определение символа, необязательно в том же модуле перевода.

Эффект эквивалентен перемещению всех ссылок на псевдоним в отдельный модуль перевода, переименованию псевдонима в алиасируемый символ, объявлению его как слабого, компиляции двух отдельных модулей перевода и выполнению связи с релоцируемым выводом (т.е. ld -r) на них.

Объявление, к которому прикреплен weakref, и которое связано с именованным target, должно быть static.

zero_call_used_regs ("choice")

Атрибут zero_call_used_regs заставляет компилятор обнулять подмножество всех регистров, используемых вызовом 7 при возвращении из функции. Это используется для повышения безопасности программы, либо смягчая атаки Return-Oriented Programming (ROP), либо предотвращая утечку информации через регистры.

Для удовлетворения различных потребностей в безопасности и одновременного контроля накладных расходов во время выполнения, параметр choice предоставляет гибкий способ выбора подмножества регистров, используемых вызовом, которые нужно обнулять. Три основных значения choice:

  • ‘skip’ — не обнуляет ни один регистр, используемый вызовом.
  • ‘used’ — обнуляет только регистры, используемые вызовом в функции. «Используемый» регистр — это тот, содержимое которого было установлено или обработано в функции.
  • ‘all’ — обнуляет все регистры, используемые вызовом.

В дополнение к этим трём основным вариантам, можно изменить ‘used’ или ‘all’ следующим образом:

  • Добавление ‘-gpr’ ограничивает обнуление универсальными регистрами.
  • Добавление ‘-arg’ ограничивает обнуление регистрам, которые иногда могут использоваться для передачи аргументов функции. Это включает все регистры аргументов, определённые механизмом вызова платформы, независимо от того, использует ли функция эти регистры для аргументов функции или нет.

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

Полный список choice:

skip

не обнуляет ни один регистр, используемый вызовом.

used

обнуляет только регистры, используемые вызовом в функции.

used-gpr

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

used-arg

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

used-gpr-arg

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

all

обнуляет все регистры, используемые вызовом.

all-gpr

обнуляет все универсальные регистры, используемые вызовом.

all-arg

обнуляет все регистры, используемые вызовом и передающие аргументы.

all-gpr-arg

обнуляет все универсальные регистры, используемые вызовом и передающие аргументы.

Из этого списка ‘used-arg’, ‘used-gpr-arg’, ‘all-arg’ и ‘all-gpr-arg’ в основном используются для смягчения атак ROP.

Значение по умолчанию для атрибута контролируется -fzero-call-used-regs.

Примечания
(7)

«Используемый вызовом» регистр — это регистр, содержимое которого может быть изменено вызовом функции; следовательно, вызывающая сторона не может предполагать, что регистр будет иметь то же содержимое при возвращении из функции, что и до вызова функции. Такие регистры также называются «изменяемыми вызовом», «сохранёнными вызывающей стороной» или «изменяемыми».

Далее: Атрибуты функции AArch64, Назад: Атрибуты функций [Содержание][Индекс]

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Common-Function-Attributes.html

Spec-Zone.ru

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