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’ не определена в том же модуле, это ошибка.
Данный атрибут требует поддержки со стороны ассемблера и файла объектов и может быть недоступен на всех целевых платформах.
alignedaligned (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++, ссылочные аргументы. Аналогично, функция, которая вызывает неконстантную функцию, обычно не должна быть константной. constructordestructorconstructor (priority)destructor (priority)-
Атрибут
constructorвызывает автоматическое выполнение функции перед входом вmain (). Аналогично, атрибутdestructorвызывает автоматическое выполнение функции после завершенияmain ()или вызоваexit (). Функции с этими атрибутами полезны для инициализации данных, которые неявно используются во время выполнения программы.На некоторых целевых платформах атрибуты также принимают целочисленный аргумент для указания приоритета, чтобы контролировать порядок выполнения конструкторов и деструкторов. Конструктор с меньшим номером приоритета выполняется до конструктора с большим номером приоритета; обратная зависимость имеет место для деструкторов. Обратите внимание, что приоритеты 0-100 зарезервированы. Таким образом, если у вас есть конструктор, который выделяет ресурс, и деструктор, который освобождает этот же ресурс, обе функции обычно имеют одинаковый приоритет. Приоритеты для конструкторов и деструкторов совпадают с теми, что указаны для объектов C++ на уровне пространства имён (см. Атрибуты C++). Однако в настоящее время порядок вызова конструкторов для объектов C++ со статической длиной хранения и функций, помеченных атрибутом
constructor, не определён. В смешанных объявлениях атрибутinit_priorityможет использоваться для навязывания определённого порядка.Использование аргументных форм атрибутов
constructorиdestructorна целевых платформах, где данная функция не поддерживается, отклоняется с ошибкой. copycopy (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); deprecateddeprecated (msg)-
Атрибут
deprecatedвызывает предупреждение, если функция используется где-либо в исходном файле. Это полезно для выявления функций, которые, как ожидается, будут удалены в будущей версии программы. Предупреждение также включает местоположение объявления устаревшей функции, что позволяет пользователям легко найти дополнительную информацию о том, почему функция устарела или что им следует сделать вместо неё. Обратите внимание, что предупреждения происходят только для использования:int old_fn () __attribute__ ((deprecated)); int old_fn (); int (*fn_ptr)() = old_fn;
приводит к предупреждению на строке 3, но не на строке 2. Необязательный аргумент msg, который должен быть строкой, выводится в предупреждении, если он присутствует.
Атрибут
deprecatedтакже может использоваться для переменных и типов (см. Атрибуты переменных, см. Атрибуты типов.)Сообщение, прикреплённое к атрибуту, зависит от настройки параметра -fmessage-length.
unavailableunavailable (msg)-
Атрибут
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/Openstrfmonтакже проверяется, как и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, каждый со своим значением аргумента, соответствующие фактические аргументы функции проверяются на соответствие всем строкам формата, обозначенным атрибутами. Эта возможность предназначена для поддержки семейства функций GNUngettext.Параметр 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 или выше.
interruptinterrupt_handler-
Многие бэкэнды GCC поддерживают атрибуты, указывающие, что функция является обработчиком прерывания, что сообщает компилятору сгенерировать последовательности входа и выхода из функции, отличающиеся от последовательностей обычных функций. Точный синтаксис и поведение зависят от целевой платформы; см. соответствующие разделы для получения подробностей.
leaf-
Вызовы внешних функций с этим атрибутом должны возвращаться в текущий модуль компиляции только через возврат или обработку исключений. В частности, функция-листок не может вызывать функции обратного вызова, переданные ей из текущего модуля компиляции, непосредственно вызывать экспортированные функциями модуля или
longjmpв модуль. Функции-листки всё ещё могут вызывать функции из других модулей компиляции и, таким образом, они не обязательно являются листками в том смысле, что не содержат никаких вызовов функций вообще.Атрибут предназначен для функций библиотек, чтобы улучшить анализ потока данных. Компилятор принимает указание о том, что любые данные, не выходящие за пределы текущего модуля компиляции, не могут использоваться или изменяться функцией-листком. Например, функция
sinявляется функцией-листком, ноqsortею не является.Обратите внимание, что функции-листки могут косвенно запускать обработчик сигнала, определённый в текущем модуле компиляции, использующий статические переменные. Аналогично, при отложенном разрешении символов, функции-листки могут вызывать косвенные функции, функции-разрешители или функции реализации которых определены в текущем модуле компиляции и используют статические переменные. Нет стандартного способа написать такой обработчик сигнала, функцию-разрешителя или функцию реализации, и всё, что вы можете сделать, это удалить атрибут
leafили пометить все такие статические переменныеvolatile. Наконец, для систем на основе ELF, поддерживающих интерпозицию символов, следует позаботиться о том, чтобы функции, определённые в текущем модуле компиляции, не предсказуемо интерпонировали другие символы, основанные на определённом режиме стандарта и определённых макросах тестов функций; в противном случае будет добавлен нежелательный обратный вызов.Атрибут не влияет на функции, определённые в текущем модуле компиляции. Это позволяет легко объединять несколько модулей компиляции в один, например, с помощью оптимизации на этапе компоновки. По этой причине атрибут не разрешается для типов для аннотирования косвенных вызовов.
mallocmalloc (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_addressno_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. Однако этот атрибут не эквивалентен комбинации других атрибутов, потому что его цель состоит в подавлении существующих и будущих оптимизаций, использующих межпроцедурный анализ, включая те, у которых нет атрибута, подходящего для их отключения индивидуально. Этот атрибут поддерживается в основном для целей тестирования компилятора. nonnullnonnull (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недоступен на всех платформах. Если вам нужно отобразить всё содержимое модуля в конкретную секцию, воспользуйтесь возможностями компоновщика. sentinelsentinel (position)-
Этот атрибут функции указывает, что аргумент в вызове функции ожидается как явный
NULL. Атрибут действителен только для функций с переменным числом аргументов. По умолчанию сигнальный элемент ожидается как последний аргумент вызова функции. Если необязательный аргумент position указан в атрибуте, сигнальный элемент должен находиться в позиции position, отсчитываемой от конца списка аргументов.__attribute__ ((sentinel)) is equivalent to __attribute__ ((sentinel(0)))
Атрибут автоматически устанавливается с позицией 0 для встроенных функций
execlиexeclp. Встроенная функцияexecleимеет атрибут, установленный с позицией 1.Допустимый
NULLв данном контексте определяется как ноль с типом указателя на любой объект. Если ваша система определяет макросNULLс целочисленным типом, вам необходимо добавить явное приведение типов. Во время установки GCC заменяет системный заголовок<stddef.h>копией, которая соответствующим образом переопределяет NULL.Предупреждения о пропущенных или неправильных сигнальных элементах включаются с -Wformat.
simdsimd("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-ассемблера и линковщика. weakrefweakref ("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.
«Используемый вызовом» регистр — это регистр, содержимое которого может быть изменено вызовом функции; следовательно, вызывающая сторона не может предполагать, что регистр будет иметь то же содержимое при возвращении из функции, что и до вызова функции. Такие регистры также называются «изменяемыми вызовом», «сохранёнными вызывающей стороной» или «изменяемыми».
Далее: Атрибуты функции 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