6.31.1 Атрибуты общих функций
Следующие атрибуты поддерживаются на большинстве целевых платформ.
alias ("target")-
Атрибут
aliasзаставляет объявление быть выведено как псевдоним для другого символа, который должен быть указан. Например,void __f () { /* Do something. */; } void f () __attribute__ ((weak, alias ("__f")));определяет ‘f’ как слабый псевдоним для ‘__f’. В C++, необходимо использовать замаскированное имя для целевой платформы. Ошибка возникает, если ‘__f’ не определено в той же единице трансляции.
Данный атрибут требует поддержки в ассемблере и объектных файлах и может быть недоступен на всех целевых платформах.
aligned (alignment)-
Этот атрибут задаёт минимальное выравнивание для функции, измеряемое в байтах.
Вы не можете использовать этот атрибут для уменьшения выравнивания функции, только для его увеличения. Однако, когда вы явно задаёте выравнивание функции, это переопределяет эффект опции -falign-functions (см. Параметры оптимизации) для этой функции.
Обратите внимание, что эффективность атрибутов
alignedможет быть ограничена внутренними ограничениями вашего компоновщика. На многих системах компоновщик может только организовать выравнивание функций до определённого максимального выравнивания. (Для некоторых компоновщиков максимальное поддерживаемое выравнивание может быть очень маленьким.) Обратитесь к документации вашего компоновщика для получения дополнительной информации.Атрибут
alignedтакже может быть использован для переменных и полей (см. Атрибуты переменных). alloc_align-
Атрибут
alloc_alignиспользуется для указания компилятору, что возвращаемое значение функции указывает на память, где минимальное выравнивание возвращаемого указателя задаётся одним из параметров функции. GCC использует эту информацию для улучшения анализа выравнивания указателей.Параметр функции, обозначающий выравнивание, задаётся одним целым числом, чьё значение является аргументом атрибута. Нумерация аргументов начинается с единицы.
Например,
void* my_memalign(size_t, size_t) __attribute__((alloc_align(1)))
объявляет, что
my_memalignвозвращает память с минимальным выравниванием, заданным параметром 1. alloc_size-
Атрибут
alloc_sizeиспользуется для указания компилятору, что возвращаемое значение функции указывает на память, где размер задаётся одним или двумя параметрами функции. GCC использует эту информацию для улучшения корректности__builtin_object_size.Параметр(ы) функции, обозначающие размер, задаются одним или двумя целыми числами, переданными в атрибут. Размер выделенной памяти либо равен значению указанного параметра функции, либо равен произведению двух указанных параметров функции. Нумерация аргументов начинается с единицы.
Например,
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-
Атрибут
assume_alignedиспользуется для указания компилятору, что возвращаемое значение функции указывает на память, где минимальное выравнивание возвращаемого указателя задаётся первым аргументом. Если атрибут имеет два аргумента, второй аргумент - это смещение несоответствия выравнивания.Например
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. bnd_instrument-
Атрибут
bnd_instrumentдля функций используется для информирования компилятора о том, что функция должна быть проинструментирована при компиляции с опцией -fchkp-instrument-marked-only. bnd_legacy-
Атрибут
bnd_legacyдля функций используется для информирования компилятора о том, что функция не должна быть проинструментирована при компиляции с опцией -fcheck-pointer-bounds. cold-
Атрибут
coldдля функций используется для информирования компилятора о том, что функция вряд ли будет выполнена. Функция оптимизируется для размера, а не для скорости, и на многих целевых платформах она помещается в специальный подраздел секции текста, так что все холодные функции находятся близко друг к другу, улучшая локальность кода нехолодных частей программы. Пути, ведущие к вызовам холодных функций в коде, помечаются механизмом предсказания ветвления как маловероятные. Таким образом, полезно помечать функции, используемые для обработки маловероятных условий, такие какperror, как холодные, чтобы улучшить оптимизацию горячих функций, которые в редких случаях вызывают помеченные функции.Когда доступна обратная связь профилирования, через -fprofile-use, холодные функции автоматически обнаруживаются, и этот атрибут игнорируется.
const-
Многие функции не проверяют никаких значений, кроме своих аргументов, и не имеют эффектов, кроме возвращаемого значения. В основном это просто немного более строгий класс, чем атрибут
pureниже, поскольку функция не может читать глобальную память.Обратите внимание, что функция, которая имеет указательные аргументы и проверяет данные, на которые указывают указатели, не должна быть объявлена
const. Аналогично, функция, которая вызывает не-constфункцию, обычно не должна бытьconst. Не имеет смысла, чтобыconstфункция возвращалаvoid. constructordestructorconstructor (priority)destructor (priority)-
Атрибут
constructorвызывает функцию автоматически перед тем, как выполнение перейдёт вmain (). Аналогично, атрибутdestructorвызывает функцию автоматически после завершенияmain ()или вызоваexit (). Функции с этими атрибутами полезны для инициализации данных, которые используются неявно во время выполнения программы.Вы можете предоставить необязательный целочисленный приоритет для управления порядком выполнения функций конструктора и деструктора. Конструктор с меньшим номером приоритета выполняется перед конструктором с большим номером приоритета; обратное соотношение справедливо для деструкторов. Таким образом, если у вас есть конструктор, который выделяет ресурс, и деструктор, который освобождает тот же ресурс, обе функции обычно имеют одинаковый приоритет. Приоритеты для функций конструктора и деструктора совпадают с теми, которые заданы для C++ объектов с областью действия всего пространства имён (см. Атрибуты C++). Однако в настоящее время порядок вызова конструкторов для C++ объектов со статической областью хранения и функций, оформленных с атрибутом
constructor, не определён. В смешанных объявлениях атрибутinit_priorityможет использоваться для навязывания конкретного порядка. deprecateddeprecated (msg)-
Атрибут
deprecatedприводит к появлению предупреждения, если функция используется где-либо в исходном файле. Это полезно для выявления функций, которые, как ожидается, будут удалены в будущей версии программы. Предупреждение также включает расположение объявления устаревшей функции, что позволяет пользователям легко найти дополнительную информацию о том, почему функция устарела или что им следует сделать вместо этого. Обратите внимание, что предупреждения появляются только при использовании:int old_fn () __attribute__ ((deprecated)); int old_fn (); int (*fn_ptr)() = old_fn;
вызывает предупреждение на строке 3, но не на строке 2. Необязательный аргумент msg, который должен быть строкой, печатается в предупреждении, если он присутствует.
Атрибут
deprecatedтакже может быть использован для переменных и типов (см. Атрибуты переменных, см. Атрибуты типов). 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-
Обычно встраивание в функцию ограничено. Для функции, помеченной этим атрибутом, каждый вызов внутри этой функции встраивается, если это возможно. Будет ли сама функция рассматриваться для встраивания, зависит от её размера и текущих параметров встраивания.
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. На целевых платформах 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(при этом остальные аргументы функции формата остаются такими же, как и для неизменённой строки). Например, объявление: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, но вызовы не могли быть проверены без атрибута.Параметр 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:void *my_memcpy (void *dst, const void *src, size_t len) { … } static void (*resolve_memcpy (void)) (void) { return my_memcpy; // we'll just always select this routine }Экспортируемый заголовочный файл, объявляющий функцию, вызываемую пользователем, содержал бы:
extern void *memcpy (void *, const void *, size_t);
что позволяет пользователю вызывать её как обычную функцию, не зная о реализации. Наконец, косвенная функция должна быть определена в том же модуле трансляции, что и функция-разрешитель:
void *memcpy (void *, const void *, size_t) __attribute__ ((ifunc ("resolve_memcpy")));Косвенные функции не могут быть слабыми. Для использования этой функции требуются версия бинарей binutils 2.20.1 или выше и GNU C Library 2.11.1 или выше.
interruptinterrupt_handler-
Многие бэкэнды GCC поддерживают атрибуты для указания того, что функция является обработчиком прерываний, что сообщает компилятору о генерации последовательностей входа и выхода из функции, отличающихся от последовательностей обычных функций. Точный синтаксис и поведение зависят от целевой платформы; см. следующие подраздёлы для получения подробностей.
leaf
-
Вызовы внешних функций с этим атрибутом должны возвращаться в текущую единицу компиляции только с помощью return или обработки исключений. В частности, функция-лист не может вызывать обратные функции, переданные ей из текущей единицы компиляции, напрямую вызывать функции, экспортированные единицей, или
longjmpв единицу. Функции-листы все еще могут вызывать функции из других единиц компиляции и, следовательно, они не обязательно являются листами в том смысле, что они вообще не содержат вызовов функций.Этот атрибут предназначен для функций библиотек для улучшения анализа потока данных. Компилятор принимает подсказку о том, что любые данные, не выходящие за пределы текущей единицы компиляции, не могут использоваться или изменяться функцией-листом. Например, функция
sin— функция-лист, ноqsort— нет.Обратите внимание, что функции-листы могут косвенно запускать обработчик сигналов, определенный в текущей единице компиляции, который использует статические переменные. Аналогично, при активном ленивом разрешении символов функции-листы могут вызывать косвенные функции, функция разрешения или функция реализации которых определены в текущей единице компиляции и используют статические переменные. Нет стандартного способа написания такого обработчика сигналов, функции разрешения или функции реализации, и все, что вы можете сделать, это удалить атрибут
leafили пометить все такие статические переменныеvolatile. Наконец, для систем на основе ELF, которые поддерживают интерпозицию символов, следует позаботиться о том, чтобы функции, определенные в текущей единице компиляции, не неожиданно интерпозировали другие символы на основе определенного стандартного режима и определенных макросов проверки функций; в противном случае будет добавлен нежелательный обратный вызов.Атрибут не оказывает влияния на функции, определенные внутри текущей единицы компиляции. Это позволяет легко объединять несколько единиц компиляции в одну, например, с помощью оптимизации на этапе компоновки. По этой причине атрибут не разрешен для типов для аннотирования косвенных вызовов.
malloc-
Это сообщает компилятору, что функция является
malloc-подобной, т.е. что указатель P, возвращаемый функцией, не может иметь общих областей с любым другим указателем, действующим в момент возврата функции, и что никакие указатели на допустимые объекты не появляются в каком-либо хранилище, адресуемом P.Использование этого атрибута может улучшить оптимизацию. Функции, такие как
mallocиcallocобладают этим свойством, поскольку они возвращают указатель на неинициализированное или обнуленное хранилище. Однако функции, такие какreallocне обладают этим свойством, так как они могут возвращать указатель на хранилище, содержащее указатели. no_icf-
Этот атрибут функции предотвращает слияние функции с другой семантически эквивалентной функцией.
no_instrument_function-
Если задан -finstrument-functions, профилирование вызовов функций генерируется при входе и выходе большинства функций, скомпилированных пользователем. Функции с этим атрибутом не инстументируются таким образом.
no_profile_instrument_function-
Атрибут
no_profile_instrument_functionдля функций используется для информирования компилятора о том, что он не должен обрабатывать код инструментирования оптимизации, основанной на обратной связи профиля. no_reorder-
Не переупорядочивать функции или переменные, помеченные
no_reorder, друг относительно друга или операторы ассемблера верхнего уровня в исполняемом файле. Фактический порядок в программе будет зависеть от командной строки компоновщика. Статические переменные, помеченные таким образом, также не удаляются. Это имеет аналогичный эффект, как опция -fno-toplevel-reorder, но применяется только к помеченным символам. 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_split_stack-
Если задан -fsplit-stack, функции имеют небольшой пролог, который определяет, следует ли разделять стек. Функции с атрибутом
no_split_stackне имеют этого пролога и, следовательно, могут работать только с небольшим объёмом доступной памяти стека. no_stack_limit-
Этот атрибут локально переопределяет опции командной строки -fstack-limit-register и -fstack-limit-symbol; он имеет эффект отключения проверки лимитов стека в функции, к которой он применён.
noclone-
Этот атрибут функции предотвращает рассмотрение функции для клонирования — механизма, который создаёт специализированные копии функций и который (в настоящее время) выполняется с помощью межпроцедурной константной подстановки.
noinline-
Этот атрибут функции предотвращает рассмотрение функции для встраивания. Если функция не имеет побочных эффектов, существуют оптимизации, помимо встраивания, которые приводят к оптимизации вызовов функций, хотя вызов функции жив. Чтобы предотвратить оптимизацию таких вызовов, поместите
asm ("");(см. Расширенный ассемблер) в вызываемой функции, чтобы служить специальным побочным эффектом.
nonnull (arg-index, …)-
Атрибут
nonnullуказывает, что некоторые параметры функций должны быть указателями, отличными от нуля. Например, объявление:extern void * my_memcpy (void *dest, const void *src, size_t len) __attribute__((nonnull (1, 2)));приводит к тому, что компилятор проверяет, что в вызовах
my_memcpy, аргументы dest и src не равны нулю. Если компилятор определяет, что в аргументе с меткой "не равно нулю" передан указатель с нулевым значением, и опция -Wnonnull включена, выводится предупреждение. Компилятор также может выбрать оптимизацию, основываясь на знаниях о том, что определённые аргументы функции никогда не будут равны нулю.Если в атрибуте
nonnullне указан список индексов аргументов, все указательные аргументы помечаются как отличные от нуля. Например, следующее объявление эквивалентно предыдущему примеру: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.Не предполагайте, что регистры, сохранённые вызывающей функцией, восстанавливаются до вызова функции
noreturn.Не имеет смысла, чтобы функция
noreturnимела тип возвращаемого значения, отличный отvoid. nothrow-
Атрибут
nothrowиспользуется для информирования компилятора о том, что функция не может выбросить исключение. Например, большинство функций в стандартной библиотеке C могут гарантировать, что не будут выброшены исключения с заметными исключениямиqsortиbsearch, принимающими указатели на функции в качестве аргументов. optimize-
Атрибут
optimizeиспользуется для указания того, что функция должна компилироваться с различными опциями оптимизации, чем указано в командной строке. Аргументы могут быть либо числами, либо строками. Числа предполагаются уровнем оптимизации. Строки, начинающиеся сO, предполагаются опцией оптимизации, в то время как другие опции предполагаются с префиксом-f. Вы также можете использовать директиву «#pragma GCC optimize» для установки опций оптимизации, влияющих на более чем одну функцию. Смотрите Функционально-специфические опции для получения подробной информации о директиве «#pragma GCC optimize».Этот атрибут следует использовать только в отладочных целях. Он не подходит для использования в производственном коде.
pure-
Многие функции не имеют эффектов, кроме возвращаемого значения, и их возвращаемое значение зависит только от параметров и/или глобальных переменных. Такую функцию можно подвергать оптимизации общего подвыражения и оптимизации циклов, так же как арифметический оператор. Эти функции должны быть объявлены с атрибутом
pure. Например,int square (int) __attribute__ ((pure));
говорит, что гипотетическая функция
squareможет вызываться меньше раз, чем указано в программе.Некоторые общие примеры чистых функций — это
strlenилиmemcmp. Интересные нечистые функции — это функции с бесконечными циклами или те, которые зависят от переменной памяти или других системных ресурсов, которые могут измениться между двумя последовательными вызовами (такие какfeofв многопоточной среде). returns_nonnull
-
Атрибут
returns_nonnullуказывает, что возвращаемое значение функции должно быть указателем, отличным от нуля. Например, объявление:extern void * mymalloc (size_t len) __attribute__((returns_nonnull));
позволяет компилятору оптимизировать вызывающие функции, зная, что возвращаемое значение никогда не будет нулевым.
returns_twice-
Атрибут
returns_twiceсообщает компилятору, что функция может возвращать значение более одного раза. Компилятор гарантирует, что все регистры будут пустыми перед вызовом такой функции и выводит предупреждение о переменных, которые могут быть перезаписаны после второго возврата из функции. Примеры таких функций —setjmpиvfork. Соответствующая функция типаlongjmp, если она есть, может потребовать маркировки атрибутомnoreturn. section ("section-name")-
Обычно компилятор размещает сгенерированный код в секции
text. Однако иногда необходимы дополнительные секции или требуется, чтобы определенные функции находились в специальных секциях. Атрибутsectionуказывает, что функция находится в конкретной секции. Например, объявление:extern void foobar (void) __attribute__ ((section ("bar")));размещает функцию
foobarв секцииbar.Некоторые форматы файлов не поддерживают произвольные секции, поэтому атрибут
sectionнедоступен на всех платформах. Если вам нужно отобразить все содержимое модуля в конкретной секции, воспользуйтесь возможностями компоновщика. sentinel-
Этот атрибут функции гарантирует, что параметр в вызове функции является явным
NULL. Атрибут действителен только для вариадических функций. По умолчанию, sentinel находится на позиции ноль, в качестве последнего параметра вызова функции. Если в атрибут передается необязательный целочисленный аргумент P, sentinel должен находиться на позиции P, считая назад от конца списка аргументов.__attribute__ ((sentinel)) is equivalent to __attribute__ ((sentinel(0)))
Атрибут автоматически устанавливается с позицией 0 для встроенных функций
execlиexeclp. Для встроенной функцииexecleатрибут устанавливается с позицией 1.Действительный
NULLв этом контексте определяется как ноль с любым типом указателя. Если ваша система определяет макросNULLс целочисленным типом, вам необходимо добавить явное приведение типа. GCC заменяетstddef.hкопией, которая соответствующим образом переопределяет NULL.Предупреждения о пропущенных или неправильных sentinel включены с помощью -Wformat.
simdsimd("mask")-
Этот атрибут позволяет создать одну или несколько версий функций, которые могут обрабатывать несколько аргументов с помощью инструкций SIMD из одного вызова. Указание этого атрибута позволяет компилятору предполагать, что такие версии доступны на этапе компоновки (приведены в той же или другой единице трансляции). Сгенерированные версии зависят от целевой платформы и описаны в соответствующем документе Vector ABI. Для целевой платформы x86_64 этот документ можно найти здесь.
Необязательный аргумент mask может иметь значение
notinbranchилиinbranch, и соответственно инструктирует компилятор генерировать не-маскированные или маскированные клоны. По умолчанию генерируются все клоны.Атрибут не должен использоваться вместе с атрибутом Cilk Plus
vectorдля той же функции.Если атрибут указан, а
#pragma omp declare simdприсутствует в объявлении, и переключатель -fopenmp или -fopenmp-simd указан, то атрибут игнорируется. stack_protect-
Этот атрибут добавляет код защиты стека к функции, если установлены флаги -fstack-protector, -fstack-protector-strong или -fstack-protector-explicit.
target (options)-
Несколько целевых back-end реализуют атрибут
targetдля указания того, что функция должна компилироваться с различными параметрами целевой платформы, отличными от указанных в командной строке. Это можно использовать, например, для компиляции функций с другой ISA (архитектурой набора инструкций), отличной от стандартной. Вы также можете использовать псевдоним #pragma GCC target для установки более чем одной функции для компиляции со специфическими параметрами целевой платформы. Подробнее о псевдониме #pragma GCC target см. в разделе Function Specific Option Pragmas.Например, на 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 Function Attributes, PowerPC Function Attributes, ARM Function Attributes и Nios II Function Attributes для получения подробной информации.
target_clones (options)-
Атрибут
target_clonesиспользуется для указания того, что функция должна быть клонирована в несколько версий, скомпилированных с разными параметрами целевой платформы, отличными от указанных в командной строке. Поддерживаемые параметры и ограничения те же, что и для атрибутаtarget.Например, на x86 вы можете скомпилировать функцию с
target_clones("sse4.1,avx"). GCC создает два клонированных варианта функции: один скомпилирован с -msse4.1, другой — с -mavx. Также создается функция-резольвер (см. атрибутifuncвыше), которая динамически выбирает клон, подходящий для текущей архитектуры. unused-
Этот атрибут, прикрепленный к функции, означает, что функция может быть неиспользуемой. GCC не выводит предупреждение для этой функции.
used-
Этот атрибут, прикрепленный к функции, означает, что для функции должен быть сгенерирован код, даже если, похоже, на нее нет ссылок. Это полезно, например, когда на функцию есть ссылки только из ассемблерного кода.
При применении к члену-функции шаблона класса C++, атрибут также означает, что функция будет инстанцирована, если класс сам инстанцируется.
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. В любом случае,weakrefподразумевает пометку объявления какweak. Без target, переданного в качестве аргументаweakrefилиalias,weakrefэквивалентноweak.static int x() __attribute__ ((weakref ("y"))); /* is equivalent to... */ static int x() __attribute__ ((weak, weakref, alias ("y"))); /* and to... */ static int x() __attribute__ ((weakref)); static int x() __attribute__ ((alias ("y")));Слабая ссылка — это псевдоним, который сам по себе не требует определения целевого символа. Если целевой символ ссылается только через слабые ссылки, то он становится
weakнеопределённым символом. Однако, если он непосредственно ссылается, то такие сильные ссылки превалируют, и определение символа необходимо, необязательно в том же блоке трансляции.Эффект эквивалентен перемещению всех ссылок на псевдоним в отдельный блок трансляции, переименованию псевдонима в целевой символ, объявлению его как слабого, компиляции двух отдельных блоков трансляции и выполнению перекомпоновки.
В настоящее время объявление, к которому прикреплён
weakref, может быть толькоstatic.
Далее: Атрибуты функций AArch64, Назад: Атрибуты функций [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/Common-Function-Attributes.html