Spec-Zone.ru › GCC 13

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++, ссылка), который подвергается доступу. Один и тот же аргумент указателя может быть соотнесен с не более чем одним отдельным атрибутом 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 заставляет объявление быть сгенерированным как псевдоним для другого символа, который должен быть предварительно объявлен с тем же типом, а для переменных — также с тем же размером и выравниванием. Объявление псевдонима с типом, отличающимся от целевого, является неопределённым и может быть диагностировано. Например, следующие объявления:

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

Атрибут 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 применяет набор атрибутов, с которыми была объявлена функция, к объявлению функции, к которой применяется этот атрибут. Атрибут предназначен для библиотек, которые определяют псевдонимы или функции разрешения, которые должны указывать тот же набор атрибутов, что и их целевые функции. Атрибут 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 всё ещё необходимы.

fd_arg
fd_arg (N)

Атрибут fd_arg может быть применён к функции, которая принимает открытый дескриптор файла в аргументе N.

Это указывает на то, что переданный дескриптор файла не должен быть закрыт. Поэтому, когда анализатор включён с -fanalyzer, анализатор может выдать диагностику -Wanalyzer-fd-use-after-close, если обнаружит путь кода, в котором функция с этим атрибутом вызывается с закрытым дескриптором файла.

Атрибут также указывает на то, что дескриптор файла должен быть проверен на корректность перед использованием. Следовательно, анализатор может выдать диагностику -Wanalyzer-fd-use-without-check, если он обнаружит путь кода, в котором функция с этим атрибутом вызывается с дескриптором файла, который не был проверен на корректность.

fd_arg_read
fd_arg_read (N)

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

Анализатор может выдать диагностическое сообщение -Wanalyzer-access-mode-mismatch, если обнаружит путь кода, в котором функция с этим атрибутом вызывается на дескрипторе файла, открытом с O_WRONLY.

fd_arg_write
fd_arg_write (N)

Атрибут fd_arg_write идентичен атрибуту fd_arg_read, за исключением того, что анализатор может выдать диагностическое сообщение -Wanalyzer-access-mode-mismatch, если обнаружит путь кода, в котором функция с этим атрибутом вызывается на дескрипторе файла, открытом с O_RDONLY.

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__. См. Функция 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, если существует путь выполнения, в котором значение передаётся более одного раза в вызов функции освобождения.
  • Анализатор рассматривает возможность того, что функция выделения может завершиться ошибкой и вернуть нуль. Если существуют пути выполнения, в которых не проверенный результат вызова функции выделения дереферируется или передаётся в функцию, требующую ненулевого аргумента, он генерирует диагностику -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, если функция освобождения используется для глобальной или стековой переменной.

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

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 может применяться к функции, которая принимает по меньшей мере один аргумент типа указателя. Он указывает, что ссылаемые аргументы должны быть указателями не равными NULL. Например, объявление:

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

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

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

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

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

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

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

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

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 используется для указания того, что функция должна быть скомпилирована с другими параметрами оптимизации, чем указанные в командной строке. Аргументы атрибута оптимизации функции ведут себя так, как будто они добавлены в командную строку.

Допустимыми аргументами являются константы неотрицательные целые числа и строки. Каждое числовое значение задаёт уровень оптимизации 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
END_OF_DOCUMENT_MARKER

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

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

Например,

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

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

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

Атрибут pure накладывает аналогичные, но менее жёсткие ограничения на определение функции, чем атрибут const: pure позволяет функции читать любую непеременную память, даже если она меняется между последовательными вызовами функции. Объявление одной и той же функции с атрибутами 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

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

Когда он применяется к методу-члену шаблона класса 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

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

internal

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

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")));

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

Эффект эквивалентен перемещению всех ссылок на псевдоним в отдельный модуль трансляции, переименованию псевдонима в алиасированный символ, объявлению его как слабого, компиляции двух отдельных модулей трансляции и выполнению линковки с релоцируемым выводом (т.е. 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)

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

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

Spec-Zone.ru

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