6.30 Объявление атрибутов функций
В GNU C вы объявляете определённые вещи о функциях, вызываемых в вашей программе, что помогает компилятору оптимизировать вызовы функций и более тщательно проверять ваш код.
Ключевое слово __attribute__ позволяет вам указывать специальные атрибуты при объявлении. Это ключевое слово сопровождается спецификацией атрибута в двойных скобках. Следующие атрибуты в настоящее время определены для функций на всех целевых платформах: aligned, alloc_size, alloc_align, assume_aligned, noreturn, returns_twice, noinline, noclone, always_inline, flatten, pure, const, nothrow, sentinel, format, format_arg, no_instrument_function, no_split_stack, section, constructor, destructor, used, unused, deprecated, weak, malloc, alias, ifunc, warn_unused_result, nonnull, returns_nonnull, gnu_inline, externally_visible, hot, cold, artificial, no_sanitize_address, no_address_safety_analysis, no_sanitize_undefined, error и warning. Несколько других атрибутов определены для функций на конкретных целевых системах. Другие атрибуты, включая section, поддерживаются для объявлений переменных (см. Атрибуты переменных) и для типов (см. Атрибуты типов).
Плагины GCC могут предоставлять свои собственные атрибуты.
Вы также можете указать атрибуты с помощью ‘__’ перед и после каждого ключевого слова. Это позволяет вам использовать их в заголовочных файлах, не беспокоясь о возможной макросе с тем же именем. Например, вы можете использовать __noreturn__ вместо noreturn.
См. Синтаксис атрибутов для подробностей точного синтаксиса использования атрибутов.
-
alias ("target") - Атрибут
aliasзаставляет объявление генерироваться как псевдоним для другого символа, который должен быть указан. Например,void __f () { /* Do something. */; } void f () __attribute__ ((weak, alias ("__f")));определяет ‘
f’ как слабый псевдоним для ‘__f’. В C++, должно использоваться закодированное имя целевого символа. Ошибка возникает, если ‘__f’ не определено в том же модуле трансляции.Не все целевые машины поддерживают этот атрибут.
-
aligned (alignment) - Этот атрибут задаёт минимальное выравнивание для функции, измеряемое в байтах.
Вы не можете использовать этот атрибут для уменьшения выравнивания функции, только для его увеличения. Однако, когда вы явно указываете выравнивание функции, это переопределяет эффект параметра
-falign-functions(см. Параметры оптимизации) для этой функции.Обратите внимание, что эффективность атрибутов
alignedможет быть ограничена внутренними ограничениями вашего компоновщика. На многих системах компоновщик может выровнять функции только до определённого максимального выравнивания. (Для некоторых компоновщиков максимальное поддерживаемое выравнивание может быть очень маленьким.) Обратитесь к документации вашего компоновщика для получения дополнительной информации.Атрибут
alignedтакже может использоваться для переменных и полей (см. Атрибуты переменных). 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возвращает память размером, равным произведению первого и второго параметра, и чтоmy_reallocвозвращает память размером, равным второму параметру. alloc_align- Атрибут
alloc_alignиспользуется для указания компилятору, что значение возвращаемого функцией указателя указывает на память, минимальное выравнивание возвращаемого указателя задаётся одним из параметров функции. GCC использует эту информацию для улучшения анализа выравнивания указателей.Параметр функции, обозначающий выравнивание, задаётся одним целым аргументом, номер которого является аргументом атрибута. Нумерация аргументов начинается с единицы.
Например,
void* my_memalign(size_t, size_t) __attribute__((alloc_align(1)))
объявляет, что
my_memalignвозвращает память с минимальным выравниванием, определяемым первым параметром. 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. always_inline- Функции, как правило, не встраиваются, если не указана оптимизация. Для функций, объявленных inline, этот атрибут встраивает функцию даже если не указан уровень оптимизации.
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. artificial- Этот атрибут полезен для небольших встроенных обёртки, которые, если это возможно, должны отображаться при отладке как единое целое. В зависимости от формата отладочной информации это либо означает маркировку функции как искусственной, либо использование местоположения вызывающей функции для всех инструкций внутри встроенного тела.
bank_switch- Когда добавляется к обработчику прерываний с портом M32C, заставляет пролог и эпилог использовать переключение банков для сохранения регистров, а не сохранять их в стеке.
flatten- Обычно встраивание в функцию ограничено. Для функции, помеченной этим атрибутом, каждый вызов внутри этой функции встраивается, если это возможно. Рассматривается ли сама функция для встраивания зависит от её размера и текущих параметров встраивания.
-
error ("message") - Если этот атрибут используется в объявлении функции, и вызов такой функции не исключён путём устранения мёртвого кода или другими оптимизациями, диагностируется ошибка, которая включает message. Это полезно для проверки во время компиляции, особенно вместе с
__builtin_constant_pи встроенными функциями, где проверка аргументов встроенной функции невозможна с помощьюextern char [(condition) ? 1 : -1];ухищрений. Хотя можно оставить функцию неопределённой, вызвав таким образом ошибку компоновки, при использовании этого атрибута проблема диагностируется раньше и с точным местоположением вызова даже при наличии встроенных функций или при отсутствии отладочной информации. -
warning ("message") - Если этот атрибут используется в объявлении функции, и вызов такой функции не исключён путём устранения мёртвого кода или другими оптимизациями, диагностируется предупреждение, которое включает message. Это полезно для проверки во время компиляции, особенно вместе с
__builtin_constant_pи встроенными функциями. Хотя можно определить функцию с сообщением в разделе.gnu.warning*, при использовании этого атрибута проблема диагностируется раньше и с точным местоположением вызова, даже при наличии встроенных функций или при отсутствии отладочной информации. cdecl- На Intel 386 атрибут
cdeclзаставляет компилятор считать, что вызывающая функция удаляет из стека пространство, используемое для передачи аргументов. Это полезно для переопределения эффектов переключателя-mrtd. const- Многие функции не проверяют никаких значений, кроме своих аргументов, и не имеют никаких эффектов, кроме возвращаемого значения. В основном это немного более строгий класс, чем атрибут
pureниже, так как функция не имеет права читать глобальную память.Обратите внимание, что функция, имеющая указательные аргументы и проверяющая данные, на которые указывают эти указатели, не должна быть объявлена
const. Аналогично, функция, вызывающая не-constфункцию, обычно не должна бытьconst. Не имеет смысла, чтобы функцияconstвозвращалаvoid.Атрибут
constне реализован в версиях GCC, предшествующих 2.5. Альтернативный способ объявления того, что функция не имеет побочных эффектов, который работает в текущей и некоторых более старых версиях, следующий:typedef int intfn (); extern const intfn square;
Этот подход не работает в GNU C++ начиная с версии 2.6.0, поскольку язык предписывает, что ‘
const’ должно быть прикреплено к возвращаемому значению. -
constructordestructorconstructor (priority)destructor (priority) - Атрибут
constructorзаставляет функцию вызываться автоматически перед тем, как выполнение войдёт вmain (). Аналогично, атрибутdestructorзаставляет функцию вызываться автоматически после того, какmain ()завершит работу илиexit ()будет вызвана. Функции с этими атрибутами полезны для инициализации данных, которые неявно используются во время выполнения программы.Вы можете предоставить необязательный целочисленный приоритет, чтобы управлять порядком выполнения функций конструкторов и деструкторов. Конструктор с меньшим номером приоритета выполняется перед конструктором с большим номером приоритета; обратная зависимость верна для деструкторов. Таким образом, если у вас есть конструктор, который выделяет ресурс, и деструктор, который освобождает тот же ресурс, обе функции обычно имеют одинаковый приоритет. Приоритеты функций конструкторов и деструкторов совпадают с приоритетами объектов C++ на уровне пространства имён (см. Атрибуты C++).
Эти атрибуты в настоящее время не реализованы для Objective-C.
-
deprecateddeprecated (msg)
- Атрибут
deprecatedприводит к появлению предупреждения, если функция используется где-либо в исходном файле. Это полезно для идентификации функций, которые, как ожидается, будут удалены в будущей версии программы. Предупреждение также включает местоположение объявления устаревшей функции, чтобы пользователи могли легко найти дополнительную информацию о причинах устаревания функции или о том, что следует сделать вместо этого. Обратите внимание, что предупреждения появляются только при использовании:int old_fn () __attribute__ ((deprecated)); int old_fn (); int (*fn_ptr)() = old_fn;
Это приводит к предупреждению на строке 3, но не на строке 2. Необязательный аргумент msg, который должен быть строкой, выводится в предупреждении, если он присутствует.
Атрибут
deprecatedтакже может использоваться для переменных и типов (см. Атрибуты переменных, см. Атрибуты типов.) disinterrupt- На целевых платформах Epiphany и MeP этот атрибут заставляет компилятор генерировать инструкции для отключения прерываний на время выполнения заданной функции.
dllexport- На целевых платформах Microsoft Windows и Symbian OS атрибут
dllexportзаставляет компилятор предоставлять глобальный указатель на указатель в DLL, чтобы он мог быть использован с атрибутомdllimport. На целевых платформах Microsoft Windows имя указателя формируется путем объединения_imp__и имени функции или переменной.Вы можете использовать
__declspec(dllexport)как синоним для__attribute__ ((dllexport))для совместимости с другими компиляторами.На системах, поддерживающих атрибут
visibility, этот атрибут также подразумевает «стандартную» видимость. Явное указание любой другой видимости является ошибкой.В предыдущих версиях GCC атрибут
dllexportигнорировался для встроенных функций, если не использовался флаг-fkeep-inline-functions. Сейчас по умолчанию все встроенные функции dllexported выводятся; однако это может привести к увеличению размера файла объекта, в этом случае старое поведение можно восстановить, используя-fno-keep-inline-dllexport.Атрибут также игнорируется для неопределённых символов.
При применении к классам C++ атрибут помечает определённые не встроенные методы-члены и статические члены данных как экспортные. Статические константы, инициализированные внутри класса, не помечаются, если они не определены вне класса.
Для целевых платформ Microsoft Windows существуют альтернативные способы включения символа в таблицу экспорта DLL, например, использование файла
.defс секциейEXPORTSили, с GNU ld, использование флага линковщика--export-all. dllimport- На целевых платформах Microsoft Windows и Symbian OS атрибут
dllimportзаставляет компилятор ссылаться на функцию или переменную через глобальный указатель на указатель, который устанавливается DLL, экспортирующей символ. Атрибут подразумеваетextern. На целевых платформах Microsoft Windows имя указателя формируется путем объединения_imp__и имени функции или переменной.Вы можете использовать
__declspec(dllimport)как синоним для__attribute__ ((dllimport))для совместимости с другими компиляторами.На системах, поддерживающих атрибут
visibility, этот атрибут также подразумевает «стандартную» видимость. Явное указание любой другой видимости является ошибкой.В настоящее время атрибут игнорируется для встроенных функций. Если атрибут применяется к определению символа, выводится сообщение об ошибке. Если символ, ранее объявленный
dllimport, позже определён, атрибут игнорируется в последующих ссылках, и выводится предупреждение. Атрибут также переопределяется последующим объявлением какdllexport.При применении к классам C++ атрибут помечает не встроенные методы-члены и статические члены данных как импортируемые. Однако атрибут игнорируется для виртуальных методов, чтобы разрешить создание vtable с использованием thunks.
На целевой платформе SH Symbian OS атрибут
dllimportтакже имеет другое влияние — он может вызывать экспорт vtable и информации о времени выполнения для класса. Это происходит, когда класс имеет конструктор dllimported или не встроенную, не чисто виртуальную функцию, и при этом класс также имеет встроенный конструктор или деструктор и имеет ключевую функцию, определённую в текущей единице трансляции.Для целевых платформ Microsoft Windows использование атрибута
dllimportдля функций не обязательно, но обеспечивает небольшую производительность, устраняя thunk в DLL. Использование атрибутаdllimportдля импортируемых переменных требовалось в старых версиях GNU линковщика, но теперь его можно избежать, передав параметр--enable-auto-importGNU линковщику. Как и в случае с функциями, использование атрибута для переменной устраняет thunk в DLL.Один недостаток использования этого атрибута заключается в том, что указатель на переменную, помеченную как
dllimport, не может использоваться как постоянный адрес. Однако указатель на функцию с атрибутомdllimportможет использоваться как постоянная инициализация; в этом случае ссылаются на адрес функции-заглушки в библиотеке импорта. На целевых платформах Microsoft Windows атрибут можно отключить для функций, установив флаг-mnop-fun-dllimport. eightbit_data- Используйте этот атрибут на H8/300, H8/300H и H8S, чтобы указать, что указанная переменная должна быть помещена в восьмибитный раздел данных. Компилятор генерирует более эффективный код для определённых операций с данными в восьмибитном разделе данных. Обратите внимание, что восьмибитный раздел данных ограничен 256 байтами данных.
Для корректной работы этого атрибута необходимо использовать GAS и GLD из GNU binutils версии 2.7 или более поздней.
exception- Используйте этот атрибут на целевой платформе NDS32, чтобы указать, что указанная функция является обработчиком исключений. Компилятор сгенерирует соответствующие разделы для использования в обработчике исключений.
exception_handler- Используйте этот атрибут на Blackfin, чтобы указать, что указанная функция является обработчиком исключений. Компилятор генерирует последовательности входа и выхода функции, подходящие для использования в обработчике исключений, когда этот атрибут присутствует.
externally_visible- Этот атрибут, присоединённый к глобальной переменной или функции, аннулирует действие командной строки
-fwhole-program, поэтому объект остаётся видимым за пределами текущей единицы компиляции.Если
-fwhole-programиспользуется вместе с-fltoиgoldиспользуется в качестве плагина линковщика, атрибутыexternally_visibleавтоматически добавляются к функциям (ещё не переменным из-за текущей проблемыgold), которые обращаются за пределами объектов LTO в соответствии с файлом разрешения, созданнымgoldДля других линковщиков, которые не могут генерировать файл разрешения, явные атрибутыexternally_visibleпо-прежнему необходимы. far- На 68HC11 и 68HC12 атрибут
farзаставляет компилятор использовать соглашение о вызове, которое обрабатывает переключение банков памяти при входе и выходе из функции. Это соглашение о вызове также является стандартным при использовании параметра-mlong-calls.На 68HC12 компилятор использует инструкции
callиrtcдля вызова и возвращения из функции.На 68HC11 компилятор генерирует последовательность инструкций для вызова специфической для платы рутины для переключения банка памяти и вызова реальной функции. Специфическая для платы рутина моделирует
call. В конце функции она переходит к специфической для платы рутине вместо использованияrtsСпецифическая для платы рутина возврата моделируетrtc.На целевых платформах MeP это заставляет компилятор использовать соглашение о вызове, которое предполагает, что вызываемая функция слишком далеко для встроенных способов адресации.
fast_interrupt- Используйте этот атрибут на портах M32C и RX, чтобы указать, что указанная функция является быстрым обработчиком прерываний. Это аналогично атрибуту
interrupt, за исключением того, чтоfreitиспользуется для возврата вместоreit. fastcall- На Intel 386 атрибут
fastcallзаставляет компилятор передавать первый аргумент (если он целого типа) в регистр ECX, а второй аргумент (если он целого типа) в регистр EDX. Последующие и другие типизированные аргументы передаются в стеке. Вызываемая функция извлекает аргументы из стека. Если количество аргументов переменное, все аргументы помещаются в стек. thiscall- На Intel 386 атрибут
thiscallзаставляет компилятор передавать первый аргумент (если он целого типа) в регистр ECX. Последующие и другие типизированные аргументы передаются в стеке. Вызываемая функция извлекает аргументы из стека. Если количество аргументов переменное, все аргументы помещаются в стек. Атрибутthiscallпредназначен для нестатических методов-членов C++. -
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на соответствие строке формата стиляprintfmy_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(при этом остальные аргументы функции формата остаются такими же, как и для немодифицированной строки). Например, объявление: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. См. Проверки форматов, специфичные для конкретных целевых машин. function_vector- Используйте этот атрибут на H8/300, H8/300H и H8S, чтобы указать, что указанная функция должна вызываться через вектор функций. Вызов функции через вектор функций уменьшает размер кода, однако вектор функций имеет ограниченный размер (максимум 128 записей на H8/300 и 64 записи на H8/300H и H8S) и разделяет пространство с вектором прерываний.
На целевых платформах SH2A этот атрибут объявляет функцию, которая должна вызываться с помощью режима адресации относительно TBR. Аргументом этого атрибута является номер записи той же функции в таблице векторов, содержащей все функции, адресованные относительно TBR. Для корректной работы TBR должен быть настроен на указание начала таблицы векторов перед вызовом любых функций с этим атрибутом. Обычно хорошее место для инициализации — процедура запуска. Таблица векторов, относительных к TBR, может иметь максимум 256 записей функций. Переходы к этим функциям генерируются с использованием специфичной для SH2A инструкции перехода без задержки JSR/N @(disp8,TBR). Для корректной работы с этим атрибутом необходимо использовать GAS и GLD из GNU binutils версии 2.7 или более поздней.
Обратитесь к примеру целевой платформы M16C, чтобы увидеть использование этого атрибута при объявлении функции.
В приложении для функции, вызываемой один раз, этот атрибут экономит не менее 8 байтов кода; если к той же функции производятся другие последовательные вызовы, он экономит 2 байта кода за каждый из этих вызовов.
На целевых платформах M16C/M32C атрибут
function_vectorобъявляет специальную функцию вызова подпрограммы страницы. Использование этого атрибута уменьшает размер кода на 2 байта за каждый сгенерированный вызов подпрограммы. Аргументом атрибута является номер записи вектора из таблицы векторов специальной страницы, которая содержит 16 младших битов адреса входа подпрограммы. Каждая таблица векторов имеет номер специальной страницы (от 18 до 255), который используется в инструкцияхjsrs. Адреса переходов процедур генерируются путем добавления 0x0F0000 (в случае целевых платформ M16C) или 0xFF0000 (в случае целевых платформ M32C) к адресам 2 байта, установленным в таблице векторов. Поэтому необходимо убедиться, что все специальные подпрограммы страницы должны быть отображены в диапазоне адресов от 0x0F0000 до 0x0FFFFF (для M16C) и от 0xFF0000 до 0xFFFFFF (для M32C).В следующем примере для каждого вызова функции
fooэкономится 2 байта.void foo (void) __attribute__((function_vector(0x18))); void foo (void) { } void bar (void) { foo(); }Если функции определены в одном файле, а вызываются в другом, то убедитесь, что это объявление записано в обоих файлах.
Этот атрибут игнорируется для целевой платформы R8C.
-
ifunc ("resolver") - Атрибут
ifuncиспользуется для пометки функции как косвенной функции с использованием расширения типа символа STT_GNU_IFUNC к стандарту ELF. Это позволяет динамически определить значение символа во время загрузки, и для конкретного процессора или других характеристик системы тогда можно выбрать оптимизированную версию процедуры. Чтобы использовать этот атрибут, сначала определите доступные реализующие функции и функцию-резольвер, которая возвращает указатель на выбранную реализующую функцию. Объявления реализующих функций должны соответствовать API функции, реализуемой функцией-резольвером, которая является функцией, возвращающей указатель на функцию void, возвращающую 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")));Косвенные функции не могут быть слабыми и требуют последних бинарных утилит (по крайней мере, версии 2.20.1) и GNU C Library (по крайней мере, версии 2.11.1).
interrupt
- Используйте этот атрибут на портах ARC, ARM, AVR, CR16, Epiphany, M32C, M32R/D, m68k, MeP, MIPS, MSP430, RL78, RX и Xstormy16, чтобы указать, что указанная функция является обработчиком прерываний. Компилятор генерирует последовательности входа и выхода для функции, подходящие для использования в обработчике прерываний, когда этот атрибут присутствует. В случае целей Epiphany он также может сгенерировать специальный раздел с кодом для инициализации таблицы векторов прерываний.
Обратите внимание, что обработчики прерываний для процессоров Blackfin, H8/300, H8/300H, H8S, MicroBlaze и SH могут быть указаны с помощью атрибута
interrupt_handler.Обратите внимание, что на ARC вам необходимо указать тип прерывания, который должен обрабатываться в параметре атрибута прерывания, например так:
void f () __attribute__ ((interrupt ("ilink1")));Допустимые значения для этого параметра:
ilink1иilink2.Обратите внимание, что на AVR аппаратное обеспечение глобально отключает прерывания при выполнении прерывания. Первая инструкция обработчика прерывания, объявленного с этим атрибутом, — это инструкция
SEIдля повторного включения прерываний. Смотрите также атрибут функцииsignal, который не вставляет инструкциюSEI. Если для одной функции указаны какsignal, так иinterrupt, тоsignalигнорируется.Обратите внимание, что для ARM вы можете указать тип прерывания, добавив необязательный параметр к атрибуту прерывания, например так:
void f () __attribute__ ((interrupt ("IRQ")));Допустимые значения для этого параметра:
IRQ,FIQ,SWI,ABORTиUNDEF.В ARMv7-M тип прерывания игнорируется, и атрибут означает, что функция может быть вызвана со значением указателя стека с выровненной по слову адресацией.
Обратите внимание, что для MSP430 вы можете предоставить аргумент к атрибуту прерывания, который указывает имя или номер. Если аргумент представляет собой число, то он указывает на ячейку в таблице векторов прерываний (0—31), которой должен быть назначен этот обработчик. Если аргумент представляет собой имя, оно рассматривается как символическое имя для ячейки вектора. Эти имена должны соответствовать соответствующим записям в скрипте компоновщика. По умолчанию распознаются имена
watchdogдля вектора 26,nmiдля вектора 30 иresetдля вектора 31.Вы также можете использовать следующие атрибуты функций для изменения того, как обычные функции взаимодействуют с функциями прерывания:
critical- Критические функции отключают прерывания при входе и восстанавливают предыдущее состояние прерывания при выходе. Критические функции также не могут иметь атрибуты
nakedилиreentrant. Они могут иметь атрибутinterrupt. reentrant- Функции, допускающие повторный вход, отключают прерывания при входе и включают их при выходе. Функции, допускающие повторный вход, также не могут иметь атрибуты
nakedилиcritical. Они могут иметь атрибутinterrupt. wakeup- Этот атрибут применяется только к функциям прерываний. Он игнорируется, если применяется к функции, не являющейся функцией прерывания. Функция прерывания пробуждения выведет процессор из любого состояния низкого энергопотребления, в котором он может находиться при выходе из функции.
Для целей Epiphany можно добавить один или несколько необязательных параметров, например так:
void __attribute__ ((interrupt ("dma0, dma1"))) universal_dma_handler ();Допустимые значения для этих параметров:
reset,software_exception,page_miss,timer0,timer1,message,dma0,dma1,wandиswi. Несколько параметров указывают на то, что для этой функции должны быть инициализированы несколько записей в таблице векторов прерываний, т. е. для каждого параметра name генерируется переход в функцию в разделе ivt_entry_name. Параметр(ы) могут быть опущены полностью, в этом случае запись в таблицу векторов прерываний не предоставляется.Обратите внимание, что на целевых платформах Epiphany прерывания включены внутри функции, если также не указан атрибут
disinterrupt.Для целей Epiphany вы также можете использовать следующий атрибут для изменения поведения обработчика прерываний:
forwarder_section- Обработчик прерывания может находиться в внешней памяти, к которой нельзя получить доступ с помощью инструкции перехода, поэтому генерируется локальный трамплин памяти для передачи управления. Единственный параметр определяет раздел, в котором размещается трамплин.
Следующие примеры являются допустимыми примерами использования этих атрибутов на целевых платформах Epiphany:
void __attribute__ ((interrupt)) universal_handler (); void __attribute__ ((interrupt ("dma1"))) dma1_handler (); void __attribute__ ((interrupt ("dma0, dma1"))) universal_dma_handler (); void __attribute__ ((interrupt ("timer0"), disinterrupt)) fast_timer_handler (); void __attribute__ ((interrupt ("dma0, dma1"), forwarder_section ("tramp"))) external_dma_handler ();Для целей MIPS вы можете использовать следующие атрибуты для изменения поведения обработчика прерываний:
use_shadow_register_set- Предполагается, что обработчик использует набор теневых регистров вместо основных регистров общего назначения.
keep_interrupts_masked- Поддерживать прерывания замаскированными для всей функции. Без этого атрибута GCC пытается повторно включить прерывания для как можно большей части функции.
use_debug_exception_return- Возврат с помощью инструкции
deret. Обработчики прерываний, у которых нет этого атрибута, возвращаются с помощью инструкцииeretвместо нее.
Вы можете использовать любое сочетание этих атрибутов, как показано ниже:
void __attribute__ ((interrupt)) v0 (); void __attribute__ ((interrupt, use_shadow_register_set)) v1 (); void __attribute__ ((interrupt, keep_interrupts_masked)) v2 (); void __attribute__ ((interrupt, use_debug_exception_return)) v3 (); void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked)) v4 (); void __attribute__ ((interrupt, use_shadow_register_set, use_debug_exception_return)) v5 (); void __attribute__ ((interrupt, keep_interrupts_masked, use_debug_exception_return)) v6 (); void __attribute__ ((interrupt, use_shadow_register_set, keep_interrupts_masked, use_debug_exception_return)) v7 ();Для целевой платформы NDS32 этот атрибут указывает, что указанная функция является обработчиком прерывания. Компилятор сгенерирует соответствующие разделы для использования в обработчике прерываний. Вы можете использовать следующие атрибуты для изменения поведения:
nested- Эта процедура обслуживания прерываний может прерываться.
not_nested- Эта процедура обслуживания прерываний не может прерываться.
nested_ready- Эта процедура обслуживания прерываний может прерываться после установки
PSW.GIE(глобального включения прерываний). Это позволяет процедуре обслуживания прерываний завершить некоторый короткий критический код перед включением прерываний. save_all- Система поможет сохранить все регистры в стеке перед входом в обработчик прерывания.
partial_save- Система поможет сохранить регистры вызывающей функции в стеке перед входом в обработчик прерывания.
В RL78 используйте
brk_interruptвместоinterruptдля обработчиков, предназначенных для использования с кодомBRK(т. е. тех, которые должны заканчиваться наRETBвместоRETI). interrupt_handler- Используйте этот атрибут для Blackfin, m68k, H8/300, H8/300H, H8S и SH, чтобы указать, что указанная функция является обработчиком прерываний. Компилятор генерирует последовательности входа и выхода для функции, подходящие для использования в обработчике прерываний, когда этот атрибут присутствует.
interrupt_thread- Используйте этот атрибут для fido, подархитектуры m68k, чтобы указать, что указанная функция является обработчиком прерываний, который предназначен для выполнения как поток. Компилятор опускает последовательности пролога/эпилога и заменяет инструкцию возврата инструкцией
sleep. Этот атрибут доступен только для fido. isr- Используйте этот атрибут для ARM для записи процедур обработки прерываний. Это псевдоним для атрибута
interruptвыше. kspisusp- При совместном использовании с
interrupt_handler,exception_handlerилиnmi_handler, генерируется код для загрузки указателя стека из регистра USP в прологе функции. l1_text- Этот атрибут указывает на функцию, которая должна быть помещена в L1 Instruction SRAM. Функция помещается в специальный раздел под названием
.l1.text. С-mfdpic, вызовы функций, использующие такую функцию в качестве вызываемой или вызывающей, используют встроенный PLT. l2- Для Blackfin этот атрибут указывает на функцию, которая должна быть помещена в L2 SRAM. Функция помещается в специальный раздел под названием
.l1.text. С-mfdpic, вызывающие функции используют встроенный PLT. leaf- Вызовы внешних функций с этим атрибутом должны возвращаться в текущую единицу компиляции только посредством возврата или обработки исключений. В частности, функции без возврата не должны вызывать обратные вызовы, переданные им из текущей единицы компиляции, или напрямую вызывать функции, экспортированные из этой единицы, или выполнять longjmp в эту единицу. Функции без возврата все же могут вызывать функции из других единиц компиляции, и поэтому они не обязательно являются функциями без возврата в том смысле, что они не содержат вызовов функций вообще.
Атрибут предназначен для функций библиотек для улучшения анализа потока данных. Компилятор принимает подсказку, что любые данные, не выходящие за пределы текущей единицы компиляции, не могут использоваться или модифицироваться функцией без возврата. Например, функция
sinявляется функцией без возврата, ноqsortне является.Обратите внимание, что функции без возврата могут вызывать сигналы, а обработчики сигналов могут быть определены в текущей единице компиляции и использовать статические переменные. Единственный способ написать такой обработчик сигналов — объявить такие переменные
volatile.Атрибут не оказывает никакого влияния на функции, определенные в текущей единице компиляции. Это позволяет легко объединять несколько единиц компиляции в одну, например, с помощью оптимизации на этапе компоновки. По этой причине атрибут недопустим для типов для аннотирования косвенных вызовов.
long_call/medium_call/short_call
- Эти атрибуты определяют, как вызывается конкретная функция на ARC, ARM и Epiphany — с
medium_call, специфичным для ARC. Эти атрибуты переопределяют-mlong-calls(см. Параметры ARM и Параметры ARC) и-mmedium-calls(см. Параметры ARC) командно-строчные переключатели и#pragma long_callsнастройки. Для ARM атрибутlong_callуказывает, что функция может находиться далеко от места вызова и потребовать другой (более дорогой) последовательности вызова. Атрибутshort_callвсегда помещает смещение функции от места вызова в инструкцию ‘BL’ напрямую.Для ARC функция, помеченная атрибутом
long_call, всегда вызывается с помощью инструкций косвенного перехода с сохранением адреса, что позволяет разместить вызываемую функцию в любом месте 32-битного адресного пространства. Функция, помеченная атрибутомmedium_call, всегда находится достаточно близко, чтобы её можно было вызвать с помощью безусловной инструкции перехода и сохранения адреса, имеющей смещение в 25 бит от места вызова. Функция, помеченная атрибутомshort_call, всегда достаточно близка, чтобы быть вызванной с помощью условной инструкции перехода и сохранения адреса, которая имеет смещение в 21 бит от места вызова. longcall/shortcall- На Blackfin, RS/6000 и PowerPC атрибут
longcallуказывает, что функция может находиться далеко от места вызова и потребовать другой (более дорогой) последовательности вызова. Атрибутshortcallуказывает, что функция всегда находится достаточно близко для использования более короткой последовательности вызова. Эти атрибуты переопределяют оба-mlongcallпереключателя и, на RS/6000 и PowerPC,#pragma longcallнастройку.См. Параметры RS/6000 и PowerPC, для получения дополнительной информации о необходимости длинных вызовов.
long_call/near/far- Эти атрибуты определяют, как вызывается конкретная функция на MIPS. Атрибуты переопределяют
-mlong-calls(см. Параметры MIPS) командно-строчный переключатель. Атрибутыlong_callиfarявляются синонимами и заставляют компилятор всегда вызывать функцию, сначала загружая её адрес в регистр, а затем используя содержимое этого регистра. Атрибутnearимеет обратный эффект; он указывает, что вызовы без позиционной независимости должны выполняться с помощью более эффективной инструкцииjal. malloc- Атрибут
mallocиспользуется для указания компилятору, что функция может обрабатываться так, как если бы любой не-NULLуказатель, который она возвращает, не мог быть связан с каким-либо другим указателем, действительным при возврате функции, и что память содержит неопределённое содержимое. Это часто улучшает оптимизацию. К стандартным функциям с этим свойством относятсяmallocиcalloc. Функции типаreallocне обладают этим свойством, так как память, на которую указывает указатель, не содержит неопределённого содержимого. mips16/nomips16- На MIPS-целевых платформах вы можете использовать атрибуты функций
mips16иnomips16для локального выбора или отключения генерации кода MIPS16. Функция с атрибутомmips16генерируется как код MIPS16, а генерация кода MIPS16 отключена для функций с атрибутомnomips16. Эти атрибуты переопределяют-mips16и-mno-mips16опции в командной строке (см. Параметры MIPS).При компиляции файлов, содержащих смешанный код MIPS16 и non-MIPS16, препроцессорная переменная
__mips16отражает настройку в командной строке, а не в отдельных функциях. Смешанный MIPS16 и non-MIPS16 код может плохо взаимодействовать с некоторыми расширениями GCC, такими как__builtin_apply(см. Создание вызовов). micromips/nomicromips- На MIPS-целевых платформах вы можете использовать атрибуты функций
micromipsиnomicromipsдля локального выбора или отключения генерации кода microMIPS. Функция с атрибутомmicromipsгенерируется как код microMIPS, а генерация кода microMIPS отключена для функций с атрибутомnomicromips. Эти атрибуты переопределяют-mmicromipsи-mno-micromipsопции в командной строке (см. Параметры MIPS).При компиляции файлов, содержащих смешанный код microMIPS и non-microMIPS, препроцессорная переменная
__mips_micromipsотражает настройку в командной строке, а не в отдельных функциях. Смешанный microMIPS и non-microMIPS код может плохо взаимодействовать с некоторыми расширениями GCC, такими как__builtin_apply(см. Создание вызовов). -
model (model-name) - На целевых платформах M32R/D используйте этот атрибут для настройки адресоваемости объекта и сгенерированного кода функции. Идентификатор model-name — это один из
small,medium, илиlarge, представляющих каждый из моделей кода.Объекты малой модели хранятся в нижних 16 МБ памяти (чтобы их адреса можно было загрузить с помощью инструкции
ld24), и вызываются с помощью инструкцииbl.Объекты средней модели могут находиться в любом месте 32-битного адресного пространства (компилятор генерирует инструкции
seth/add3для загрузки их адресов) и вызываются с помощью инструкцииbl.Объекты большой модели могут находиться в любом месте 32-битного адресного пространства (компилятор генерирует инструкции
seth/add3для загрузки их адресов) и могут быть недоступны с помощью инструкцииbl(компилятор генерирует гораздо более медленную последовательность инструкцийseth/add3/jl).На IA-64 используйте этот атрибут для настройки адресоваемости объекта. В настоящее время единственный поддерживаемый идентификатор для model-name — это
small, указывающий на адресоваемость через «малые» (22-битные) адреса (чтобы их адреса можно было загрузить с помощью инструкцииaddl). Предупреждение: такая адресация по определению не является независимой от позиции, поэтому этот атрибут не должен использоваться для объектов, определённых разделяемыми библиотеками. ms_abi/sysv_abi- На 32-битных и 64-битных (i?86|x86_64)-*-* целевых платформах вы можете использовать атрибут ABI для указания используемой соглашения о вызовах для функции. Атрибут
ms_abiуказывает компилятору использовать Microsoft ABI, в то время как атрибутsysv_abiуказывает компилятору использовать ABI, используемый в GNU/Linux и других системах. По умолчанию используется Microsoft ABI при нацеливании на Windows. На всех остальных системах по умолчанию используется x86/AMD ABI.Обратите внимание, что атрибут
ms_abiдля 64-битных целевых платформ Microsoft Windows в настоящее время требует опцию-maccumulate-outgoing-args. -
callee_pop_aggregate_return (number) - На 32-битных i?86-*-* целевых платформах вы можете использовать этот атрибут для управления тем, как агрегаты возвращаются в памяти. Если вызывающий процесс отвечает за удаление скрытого указателя вместе с остальными аргументами, задайте number равным нулю. Если вызываемый процесс отвечает за удаление скрытого указателя, задайте number равным единице.
Стандартный ABI i386 предполагает, что вызываемый процесс удаляет скрытый указатель со стека. Однако на 32-битных i386 целевых платформах Microsoft Windows компилятор предполагает, что вызывающий процесс удаляет скрытый указатель со стека.
ms_hook_prologue- На 32-битных i[34567]86-*-* и 64-битных x86_64-*-* целевых платформах вы можете использовать этот атрибут функции для того, чтобы GCC генерировал «пролог» функции «горячей подмены», используемый в функциях API Win32 в Microsoft Windows XP Service Pack 2 и более поздних версиях.
-
hotpatch (halfwords-before-function-label,halfwords-after-function-label) - На целевых платформах S/390 System z вы можете использовать этот атрибут функции для того, чтобы GCC генерировал «пролог» функции «горячей подмены». Если одновременно используется опция
-mhotpatch=командной строки, атрибутhotpatchимеет приоритет. Первый из двух аргументов задаёт количество полуслов, добавляемых перед меткой функции. Второй аргумент может быть использован для задания количества полуслов, добавляемых после метки функции. Для обоих аргументов максимальное допустимое значение равно 1000000.Если оба аргумента равны нулю, горячая подмена отключена.
naked- Используйте этот атрибут на портах ARM, AVR, MCORE, MSP430, NDS32, RL78, RX и SPU для обозначения того, что указанной функции не требуются генерируемые компилятором прологи/эпилоги. Программист должен обеспечить эти последовательности. Единственными операциями, которые можно безопасно включить в функции naked, являются
asmоператоры, не имеющие операндов. Все остальные операторы, включая объявления локальных переменных,ifоператоры и т. д., следует избегать. Функции naked должны использоваться для реализации тела ассемблерных функций, позволяя компилятору строить необходимые объявления функций для ассемблера. near- На 68HC11 и 68HC12 атрибут
nearзаставляет компилятор использовать стандартное соглашение о вызовах, основанное наjsrиrts. Этот атрибут может быть использован для отмены действия опции-mlong-calls.На целевых платформах MeP этот атрибут заставляет компилятор считать, что вызываемая функция находится достаточно близко, чтобы использовать стандартное соглашение о вызовах, переопределяя опцию
-mtfкомандной строки. nesting- Используйте этот атрибут совместно с
interrupt_handler,exception_handlerилиnmi_handlerдля указания того, что код входа в функцию должен включать обработку вложенных прерываний или исключений. nmi_handler- Используйте этот атрибут на Blackfin для обозначения указанной функции как обработчика NMI. Компилятор генерирует последовательности входа и выхода из функции, подходящие для использования в обработчике NMI, когда этот атрибут присутствует.
nocompression- На MIPS-целевых платформах вы можете использовать атрибут функции
nocompressionдля локального отключения генерации кода MIPS16 и microMIPS. Этот атрибут переопределяет опции-mips16и-mmicromipsв командной строке (см. Параметры MIPS). no_instrument_function- Если указано
-finstrument-functions, для большинства функций, скомпилированных пользователем, генерируются операции профилирования вызовов функций при входе и выходе. Функции с этим атрибутом не так сильно инструментированы.
no_split_stack- Если
-fsplit-stackзадано, функции имеют небольшой пролог, который определяет, следует ли разделять стек. Функции с атрибутомno_split_stackне имеют этого пролога и, следовательно, могут выполняться с небольшим объёмом доступной памяти стека. noinline- Этот атрибут функции предотвращает рассмотрение функции для инлайнинга. Если функция не имеет побочных эффектов, существуют оптимизации, помимо инлайнинга, которые приводят к тому, что вызовы функций оптимизируются, хотя вызов функции жив. Чтобы не допустить оптимизации таких вызовов, поместите
asm ("");(см. Расширенный ассемблер) в вызываемую функцию, чтобы она служила специальным побочным эффектом.
noclone- Этот атрибут функции предотвращает рассмотрение функции для клонирования — механизма, который генерирует специализированные копии функций, и который (в настоящее время) выполняется посредством межпроцедурной константной проработки.
-
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)); returns_nonnull- Атрибут
returns_nonnullуказывает, что значение возврата функции должно быть указателем на непустое значение. Например, объявление:extern void * mymalloc (size_t len) __attribute__((returns_nonnull));
позволяет компилятору оптимизировать вызывающие функции, основываясь на знании, что значение возврата никогда не будет нулевым.
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.Атрибут
noreturnне реализован в версиях GCC, более ранних, чем 2.5. Альтернативный способ объявить, что функция не возвращает значение, который работает в текущей версии и в некоторых более старых версиях, следующий:typedef void voidfn (); volatile voidfn fatal;
Этот подход не работает в GNU C++.
nothrow- Атрибут
nothrowиспользуется для информирования компилятора о том, что функция не может бросить исключение. Например, большинство функций в стандартной библиотеке C могут быть гарантированы как не бросающие исключения, за исключениемqsortиbsearch, которые принимают аргументы указателей на функции. Атрибутnothrowне реализован в версиях GCC, более ранних, чем 3.3. nosave_low_regs- Используйте этот атрибут на целях SH, чтобы указать, что функция
interrupt_handlerне должна сохранять и восстанавливать регистры R0..R7. Это можно использовать на целевых платформах SH3* и SH4*, которые имеют второй набор регистров R0..R7 для нерекурсивных обработчиков прерываний. optimize- Атрибут
optimizeиспользуется для указания того, что функция должна компилироваться с различными параметрами оптимизации, чем указанные в командной строке. Аргументы могут быть числами или строками. Числа предполагаются уровнем оптимизации. Строки, начинающиеся сO, предполагаются параметром оптимизации, в то время как другие параметры предполагаются используемыми с префиксом-f. Вы также можете использовать директиву «#pragma GCC optimize» для установки параметров оптимизации, которые влияют на более чем одну функцию. Подробнее см. Функционально-специфические параметры оптимизации.Это можно использовать, например, для компиляции часто выполняемых функций с более агрессивными параметрами оптимизации, которые генерируют более быстрый и больший код, в то время как другие функции могут компилироваться с менее агрессивными параметрами.
OS_main/OS_task- На AVR функции с атрибутами
OS_mainилиOS_taskне сохраняют/восстанавливают сохранённые регистры вызова в своих прологах/эпилогах.Атрибут
OS_mainможно использовать, когда гарантируется, что прерывания отключены в момент входа в функцию. Это экономит ресурсы, когда указатель стека должен быть изменён для настройки фрейма для локальных переменных.Атрибут
OS_taskможно использовать, когда нет гарантии, что прерывания отключены в момент входа в функцию, например, для функций задач в многопоточной операционной системе. В этом случае изменение указателя стека защищается сохранением/очисткой/восстановлением флага глобального разрешения прерываний.Различия с атрибутом функции
naked:-
Функции
nakedне имеют инструкции возврата, в то время как функцииOS_mainиOS_taskимеют инструкцию возвратаRETилиRETI. -
Функции
nakedне устанавливают фрейм для локальных переменных или указатель фрейма, в то время как функцииOS_mainиOS_taskделают это по мере необходимости.
-
Функции
pcs- Атрибут
pcsможет использоваться для управления соглашением вызова, используемым для функции на ARM. Атрибут принимает аргумент, который указывает соглашение вызова, которое следует использовать.При компиляции с использованием ABI AAPCS (или его вариантом) допустимые значения аргумента —
"aapcs"и"aapcs-vfp". Чтобы использовать вариант, отличный от"aapcs", компилятор должен иметь разрешение использовать соответствующие регистры сопроцессора (то есть, регистры VFP должны быть доступны, чтобы использовать"aapcs-vfp"). Например,/* Argument passed in r0, and result returned in r0+r1. */ double f2d (float) __attribute__((pcs("aapcs")));Функции с переменным числом аргументов всегда используют соглашение вызова
"aapcs"и компилятор отклоняет попытки указать альтернативу. pure- Многие функции не имеют эффектов, кроме значения возврата, и их значение возврата зависит только от параметров и/или глобальных переменных. Такая функция может быть объектом исключения общих подвыражений и оптимизации циклов, подобно арифметическому оператору. Эти функции должны объявляться с атрибутом
pure. Например,int square (int) __attribute__ ((pure));
указывает, что гипотетическая функция
squareможно вызывать меньше раз, чем указано в программе.Некоторые примеры чистых функций —
strlenилиmemcmp. Интересные нечистые функции — функции с бесконечными циклами или те, которые зависят от переменной памяти или других системных ресурсов, которые могут изменяться между двумя последовательными вызовами (например,feofв многопоточной среде).Атрибут
pureне реализован в версиях GCC, более ранних, чем 2.96. hot- Атрибут
hotдля функции информирует компилятор о том, что функция — горячая точка компилируемой программы. Функция оптимизируется более агрессивно и на многих целевых платформах помещается в специальный подсекции секции текста, так что все горячие функции располагаются близко друг к другу, улучшая локальность.Когда доступна обратная связь профилирования, через
-fprofile-use, горячие функции автоматически обнаруживаются, и этот атрибут игнорируется.Атрибут
hotдля функций не реализован в версиях GCC, более ранних, чем 4.3.Атрибут
hotдля метки информирует компилятор о том, что пути, следующие за меткой, более вероятны, чем пути, которые не проаннотированы. Этот атрибут используется в случаях, когда__builtin_expectне может быть использован, например, с вычислением переходов илиasm goto.Атрибут
hotдля меток не реализован в версиях GCC, более ранних, чем 4.8. cold- Атрибут
coldдля функций сообщает компилятору, что функция, скорее всего, не будет выполнена. Функция оптимизируется для размера, а не для скорости, и на многих целевых платформах она помещается в специальную секцию секции текста, так что все холодные функции располагаются близко друг к другу, улучшая локальность кода для нехолодных частей программы. Пути, ведущие к вызову холодных функций в коде, отмечаются механизмом предсказания ветвлений как маловероятные. Поэтому полезно пометить функции, используемые для обработки маловероятных условий, такие какperror, как холодные, чтобы улучшить оптимизацию горячих функций, которые в редких случаях вызывают помеченные функции.Когда доступна обратная связь профилирования, через
-fprofile-use, холодные функции автоматически обнаруживаются, и этот атрибут игнорируется.Атрибут
coldдля функций не реализован в версиях GCC, более ранних, чем 4.3.Атрибут
coldдля меток информирует компилятор о том, что путь, следующий за меткой, маловероятен. Этот атрибут используется в случаях, когда__builtin_expectнельзя использовать, например, с вычислением переходов илиasm goto.Атрибут
coldдля меток не реализован в версиях GCC, более ранних, чем 4.8. -
no_sanitize_addressno_address_safety_analysis - Атрибут
no_sanitize_addressдля функций сообщает компилятору, что при компиляции с параметром-fsanitize=addressон не должен инструментировать обращения к памяти в функции. Атрибутno_address_safety_analysis— устаревший псевдоним атрибутаno_sanitize_address, новый код должен использоватьno_sanitize_address. no_sanitize_undefined
- Атрибут
no_sanitize_undefinedдля функций используется для информирования компилятора о том, что при компиляции с опцией-fsanitize=undefinedон не должен проверять неопределённое поведение в функции. -
regparm (число) - На Intel 386 атрибут
regparmзаставляет компилятор передавать аргументы с первого по число, если они имеют целочисленный тип, в регистрах EAX, EDX и ECX вместо стека. Функции, принимающие переменное количество аргументов, по-прежнему передают все свои аргументы через стек.Следует учитывать, что на некоторых системах ELF этот атрибут не подходит для глобальных функций в разделяемых библиотеках с отложенной привязкой (по умолчанию). Отложенная привязка отправляет первый вызов через код разрешения в загрузчике, который может предполагать, что EAX, EDX и ECX могут быть испорчены, в соответствии со стандартными правилами вызовов. Solaris 8 затронут этим. Предполагается, что системы с библиотекой GNU C версии 2.1 или выше и FreeBSD безопасны, поскольку загрузчики там сохраняют EAX, EDX и ECX. (Отложенная привязка может быть отключена с помощью компоновщика или загрузчика, если это необходимо, чтобы избежать проблемы.)
reset- Используйте этот атрибут для целевой платформы NDS32, чтобы указать, что указанная функция является обработчиком сброса. Компилятор сгенерирует соответствующие секции для использования в обработчике сброса. Вы можете использовать следующие атрибуты для предоставления дополнительной обработки исключений:
nmi- Укажите пользовательскую функцию для обработки исключения NMI.
warm- Укажите пользовательскую функцию для обработки исключения тёплого сброса.
sseregparm- На Intel 386 с поддержкой SSE атрибут
sseregparmзаставляет компилятор передавать до 3 аргументов с плавающей точкой в регистрах SSE вместо стека. Функции, принимающие переменное количество аргументов, по-прежнему передают все свои аргументы с плавающей точкой через стек. force_align_arg_pointer- На Intel x86 атрибут
force_align_arg_pointerможно применять к отдельным определениям функций, генерируя альтернативный пролог и эпилог, которые перевыравнивают стек во время выполнения при необходимости. Это поддерживает смешение кода старого формата, работающего со стеком, выровненным по 4 байта, с современным кодом, поддерживающим 16-байтовый стек для совместимости с SSE. renesas- На целевых платформах SH этот атрибут указывает, что функция или структура следуют ABI Renesas.
resbank- На целевой платформе SH2A этот атрибут включает быстрое сохранение и восстановление регистров с использованием банка регистров для
interrupt_handlerпроцедур. Сохранение в банк выполняется автоматически после того, как процессор принимает прерывание, использующее банк регистров.Девятнадцать 32-битных регистров, составляющих регистры общего назначения R0–R14, регистр управления GBR и системные регистры MACH, MACL и PR, а также смещение адреса таблицы векторов сохраняются в банк регистров. Банки регистров складываются в порядке LIFO (первым вошёл, последним вышел). Восстановление из банка выполняется путём выдачи инструкции RESBANK.
returns_twice- Атрибут
returns_twiceсообщает компилятору, что функция может возвратить значение более одного раза. Компилятор гарантирует, что все регистры будут освобождены перед вызовом такой функции и выводит предупреждение о переменных, которые могут быть испорчены после второго возвращения из функции. Примерами таких функций являютсяsetjmpиvfork. Соответствующая функция типаlongjmp, если она существует, может потребовать маркировки атрибутомnoreturn. saveall- Используйте этот атрибут на платформах Blackfin, H8/300, H8/300H и H8S для указания, что все регистры, кроме указателя стека, должны быть сохранены в прологе, независимо от того, используются ли они или нет.
save_volatiles- Используйте этот атрибут на платформе MicroBlaze для указания того, что функция является обработчиком прерываний. Все переменные регистры (в дополнение к постоянным регистрам) сохраняются в прологе функции. Если функция является листом, сохраняются только переменные регистры, используемые функцией. Вместо возврата из прерывания генерируется обычный возврат из функции.
-
section ("имя_секции") - Обычно компилятор помещает сгенерированный код в секцию
text. Однако иногда вам нужны дополнительные секции или вы хотите, чтобы определённые функции появлялись в специальных секциях. Атрибутsectionуказывает, что функция находится в определённой секции. Например, объявление:extern void foobar (void) __attribute__ ((section ("bar")));размещает функцию
foobarв секцииbar.Некоторые форматы файлов не поддерживают произвольные секции, поэтому атрибут
sectionнедоступен на всех платформах. Если вам нужно отобразить всё содержимое модуля в конкретной секции, рассмотрите использование возможностей компоновщика. sentinel- Этот атрибут функции гарантирует, что параметр в вызове функции является явным
NULL. Атрибут действителен только для вариативных функций. По умолчанию контрольный символ находится в позиции ноль, в качестве последнего параметра вызова функции. Если к атрибуту добавлен необязательный целочисленный параметр P, контрольный символ должен находиться в позиции P, считая обратно от конца списка аргументов.__attribute__ ((sentinel)) is equivalent to __attribute__ ((sentinel(0)))
Атрибут автоматически устанавливается с положением 0 для встроенных функций
execlиexeclp. Для встроенной функцииexecleатрибут устанавливается с положением 1.Действительный
NULLв данном контексте определяется как ноль с любым указательным типом. Если ваша система определяет макросNULLс целочисленным типом, вам нужно добавить явное приведение типа. GCC заменяетstddef.hкопией, которая соответствующим образом переопределяет NULL.Предупреждения о пропущенных или неверных контрольных символах включены с
-Wformat. short_call- См.
long_call/short_call. shortcall- См.
longcall/shortcall. signal- Используйте этот атрибут на AVR, чтобы указать, что указанная функция является обработчиком прерываний. Компилятор генерирует последовательности входа и выхода функции, подходящие для использования в обработчике прерываний, если этот атрибут присутствует.
См. также атрибут функции
interrupt.Аппаратное обеспечение AVR глобально отключает прерывания при выполнении прерывания. Функции обработчиков прерываний, определённые с атрибутом
signal, не включают прерывания повторно. Разрешение прерываний в обработчикеsignalбезопасно. Это «сохранение» относится только к коду, сгенерированному компилятором, а не к схеме IRQ приложения, которая является обязанностью приложения.Если и
signal, иinterruptуказаны для одной функции,signalигнорируется. sp_switch- Используйте этот атрибут на SH для указания, что функция
interrupt_handlerдолжна переключиться на альтернативный стек. Ожидается строковый аргумент, который указывает на глобальную переменную, содержащую адрес альтернативного стека.void *alt_stack; void f () __attribute__ ((interrupt_handler, sp_switch ("alt_stack"))); stdcall- На Intel 386 атрибут
stdcallзаставляет компилятор предполагать, что вызываемая функция удаляет из стека пространство, используемое для передачи аргументов, если только она не принимает переменное количество аргументов. syscall_linkage- Этот атрибут используется для изменения соглашения о вызовах IA-64, помечая все входные регистры как активные во всех выходах из функции. Это позволяет перезапустить системный вызов после прерывания без необходимости сохранения/восстановления входных регистров. Это также предотвращает утечку данных ядра в код приложения.
target
- Атрибут
targetиспользуется для указания того, что функция должна быть скомпилирована с различными параметрами целевой архитектуры, отличными от указанных в командной строке. Это может быть использовано, например, для компиляции функций с другой ISA (архитектурой набора команд), отличной от стандартной. Также можно использовать псевдоним ‘#pragma GCC target’, чтобы задать более одной функции для компиляции со специфическими параметрами целевой архитектуры. Подробную информацию о псевдониме ‘#pragma GCC target’ см. в разделе Функциональные специфические параметры опций.Например, на 386 можно скомпилировать одну функцию с
target("sse4.1,arch=core2")и другую сtarget("sse4a,arch=amdfam10"). Это эквивалентно компиляции первой функции с параметрами-msse4.1и-march=core2, а второй функции с параметрами-msse4aи-march=amdfam10. Пользователь должен убедиться, что функция вызывается только на машине, поддерживающей конкретную ISA, для которой она скомпилирована (например, используяcpuidна 386 для определения используемых битов функций и семейств архитектуры).int core2_func (void) __attribute__ ((__target__ ("arch=core2"))); int sse3_func (void) __attribute__ ((__target__ ("sse3")));Можно использовать несколько строк для указания нескольких параметров или разделить параметры запятой (‘
,’).Атрибут
targetв настоящее время реализован только для целей i386/x86_64, PowerPC и Nios II. Поддерживаемые параметры специфичны для каждой целевой архитектуры.На 386 разрешены следующие параметры:
- ‘
abm’- ‘
no-abm’ - ‘
- Включение/выключение генерации инструкций с расширенными битами.
- ‘
aes’- ‘
no-aes’ - ‘
- Включение/выключение генерации инструкций AES.
- ‘
default’ - См. Многоверсионность функций, где он используется для указания стандартной версии функции.
- ‘
mmx’- ‘
no-mmx’ - ‘
- Включение/выключение генерации MMX инструкций.
- ‘
pclmul’- ‘
no-pclmul’ - ‘
- Включение/выключение генерации инструкций PCLMUL.
- ‘
popcnt’- ‘
no-popcnt’ - ‘
- Включение/выключение генерации инструкции POPCNT.
- ‘
sse’- ‘
no-sse’ - ‘
- Включение/выключение генерации SSE инструкций.
- ‘
sse2’- ‘
no-sse2’ - ‘
- Включение/выключение генерации SSE2 инструкций.
- ‘
sse3’- ‘
no-sse3’ - ‘
- Включение/выключение генерации SSE3 инструкций.
- ‘
sse4’- ‘
no-sse4’ - ‘
- Включение/выключение генерации SSE4 инструкций (как SSE4.1, так и SSE4.2).
- ‘
sse4.1’- ‘
no-sse4.1’ - ‘
- Включение/выключение генерации инструкций sse4.1.
- ‘
sse4.2’- ‘
no-sse4.2’ - ‘
- Включение/выключение генерации инструкций sse4.2.
- ‘
sse4a’- ‘
no-sse4a’ - ‘
- Включение/выключение генерации инструкций SSE4A.
- ‘
fma4’- ‘
no-fma4’ - ‘
- Включение/выключение генерации инструкций FMA4.
- ‘
xop’- ‘
no-xop’ - ‘
- Включение/выключение генерации инструкций XOP.
- ‘
lwp’- ‘
no-lwp’ - ‘
- Включение/выключение генерации инструкций LWP.
- ‘
ssse3’- ‘
no-ssse3’ - ‘
- Включение/выключение генерации инструкций SSSE3.
- ‘
cld’- ‘
no-cld’ - ‘
- Включение/выключение генерации CLD перед операциями перемещения строк.
- ‘
fancy-math-387’- ‘
no-fancy-math-387’ - ‘
- Включение/выключение генерации инструкций
sin,cos, иsqrtна 387 FPU (плавающей точкой). - ‘
fused-madd’- ‘
no-fused-madd’ - ‘
- Включение/выключение генерации слиянных инструкций умножения/сложения.
- ‘
ieee-fp’- ‘
no-ieee-fp’ - ‘
- Включение/выключение генерации операций с плавающей точкой, зависящих от арифметики IEEE.
- ‘
inline-all-stringops’- ‘
no-inline-all-stringops’ - ‘
- Включение/выключение встраивания строковых операций.
- ‘
inline-stringops-dynamically’- ‘
no-inline-stringops-dynamically’ - ‘
- Включение/выключение генерации встроенного кода для небольших строковых операций и вызова процедур библиотеки для больших операций.
- ‘
align-stringops’- ‘
no-align-stringops’ - ‘
- Выравнивать/не выравнивать целевой адрес встроенных строковых операций.
- ‘
recip’- ‘
no-recip’ - ‘
- Включить/выключить генерацию инструкций RCPSS, RCPPS, RSQRTSS и RSQRTPS, за которыми следует дополнительный шаг Ньютона-Рафсона вместо выполнения деления с плавающей точкой.
- ‘arch=ARCH’
- Указать архитектуру, для которой генерируется код при компиляции функции.
- ‘tune=TUNE’
- Указать архитектуру, для оптимизации компиляции функции.
- ‘fpmath=FPMATH’
- Указать, какой блок плавающей точки использовать. Параметр
target("fpmath=sse,387")должен быть указан какtarget("fpmath=sse+387"), так как запятая разделяет различные параметры.
На PowerPC разрешены следующие параметры:
- ‘
- ‘
altivec’- ‘
no-altivec’ - ‘
- Генерировать код, использующий (не использующий) инструкции AltiVec. В 32-битном коде вы не можете включить инструкции AltiVec, если
-mabi=altivecне используется в командной строке. - ‘
cmpb’- ‘
no-cmpb’ - ‘
- Генерировать код, использующий (не использующий) инструкцию сравнения байтов, реализованную на процессоре POWER6 и других процессорах, поддерживающих архитектуру PowerPC V2.05.
- ‘
dlmzb’- ‘
no-dlmzb’ - ‘
- Генерировать код, использующий (не использующий) инструкцию поиска строк ‘
dlmzb’ на процессорах IBM 405, 440, 464 и 476. Эта инструкция генерируется по умолчанию при нацеливании на эти процессоры. - ‘
fprnd’- ‘
no-fprnd’ - ‘
- Генерировать код, использующий (не использующий) инструкции FP округления к целому, реализованные на процессоре POWER5+ и других процессорах, поддерживающих архитектуру PowerPC V2.03.
- ‘
hard-dfp’- ‘
no-hard-dfp’ - ‘
- Генерировать код, использующий (не использующий) инструкции десятичной плавающей точки, реализованные на некоторых процессорах POWER.
- ‘
isel’- ‘
no-isel’ - ‘
- Генерировать код, использующий (не использующий) инструкцию ISEL.
- ‘
mfcrf’- ‘
no-mfcrf’ - ‘
- Генерировать код, использующий (не использующий) инструкцию перемещения из поля регистра состояния, реализованную на процессоре POWER4 и других процессорах, поддерживающих архитектуру PowerPC V2.01.
- ‘
mfpgpr’- ‘
no-mfpgpr’ - ‘
- Генерировать код, использующий (не использующий) инструкции перемещения FP в/из регистры общего назначения, реализованные на процессоре POWER6X и других процессорах, поддерживающих расширенную архитектуру PowerPC V2.05.
- ‘
mulhw’- ‘
no-mulhw’ - ‘
- Генерировать код, использующий (не использующий) инструкции умножения полуслов и умножения-складывания на процессорах IBM 405, 440, 464 и 476. Эти инструкции генерируются по умолчанию при нацеливании на эти процессоры.
- ‘
multiple’- ‘
no-multiple’ - ‘
- Генерировать код, использующий (не использующий) инструкции загрузки/хранения нескольких слов.
- ‘
update’- ‘
no-update’ - ‘
- Генерировать код, использующий (не использующий) инструкции загрузки или сохранения, обновляющие базовый регистр до адреса вычисленного расположения памяти.
- ‘
popcntb’- ‘
no-popcntb’ - ‘
- Генерировать код, использующий (не использующий) инструкцию подсчёта единиц и оценку обратного двойной точности FP, реализованные на процессоре POWER5 и других процессорах, поддерживающих архитектуру PowerPC V2.02.
- ‘
popcntd’- ‘
no-popcntd’ - ‘
- Генерировать код, использующий (не использующий) инструкцию подсчёта единиц, реализованную на процессоре POWER7 и других процессорах, поддерживающих архитектуру PowerPC V2.06.
- ‘
powerpc-gfxopt’- ‘
no-powerpc-gfxopt’ - ‘
- Генерировать код, использующий (не использующий) необязательные инструкции архитектуры PowerPC в группе Graphics, включая выбор плавающей точки.
- ‘
powerpc-gpopt’- ‘
no-powerpc-gpopt’ - ‘
- Генерировать код, использующий (не использующий) необязательные инструкции архитектуры PowerPC в группе Общего назначения, включая квадратный корень плавающей точки.
- ‘
recip-precision’- ‘
no-recip-precision’ - ‘
- Предполагать (не предполагать), что инструкции оценки обратного значения обеспечивают оценку большей точности, чем предписано ABI powerpc.
- ‘
string’- ‘
no-string’ - ‘
- Генерировать код, использующий (не использующий) инструкции загрузки строки и инструкции сохранения слов строки для сохранения нескольких регистров и выполнения небольших блочных перемещений.
- ‘
vsx’- ‘
no-vsx’ - ‘
- Генерировать код, использующий (не использующий) векторные/скалярные (VSX) инструкции, а также включить использование встроенных функций, позволяющих получить более прямой доступ к набору инструкций VSX. В 32-битном коде вы не можете включить инструкции VSX или AltiVec, если
-mabi=altivecне используется в командной строке. - ‘
friz’- ‘
no-friz’ - ‘
- Генерировать (не генерировать) инструкцию
friz, когда используется опция-funsafe-math-optimizations, чтобы оптимизировать округление значения с плавающей точкой до 64-битного целого и обратно в значение с плавающей точкой. Инструкцияfrizне возвращает то же значение, если число с плавающей точкой слишком велико, чтобы уместиться в целое. - ‘
avoid-indexed-addresses’- ‘
no-avoid-indexed-addresses’ - ‘
- Генерировать код, который пытается избежать (не избегать) использования индексированных инструкций загрузки или сохранения.
- ‘
paired’- ‘
no-paired’ - ‘
- Генерировать код, использующий (не использующий) генерацию PAIRED инструкций simd.
- ‘
longcall’- ‘
no-longcall’ - ‘
- Генерировать код, предполагающий (не предполагающий), что все вызовы находятся далеко, так что требуется более длинная и дорогая последовательность вызовов.
- ‘cpu=CPU’
- Указывает архитектуру для генерации кода при компиляции функции. Если вы выбираете атрибут
target("cpu=power7")при генерации 32-битного кода, инструкции VSX и AltiVec не генерируются, если вы не используете опцию-mabi=altivecв командной строке. - ‘tune=TUNE’
- Указывает архитектуру для настройки при компиляции функции. Если вы не указываете атрибут
target("tune=TUNE"), и вы указываете атрибутtarget("cpu=CPU"), компиляция настраивается для архитектуры CPU, а не для настройки по умолчанию, указанной в командной строке.
При компиляции для Nios II разрешены следующие опции:
- ‘custom-insn=N’
- ‘no-custom-insn’
- Атрибут ‘custom-insn=N’ локально включает использование пользовательской инструкции с кодированием N при генерации кода, использующего insn. Аналогично, ‘no-custom-insn’ локально запрещает использование пользовательской инструкции insn. Эти атрибуты целевого назначения соответствуют параметрам командной строки -mcustom-insn=N и -mno-custom-insn и поддерживают тот же набор ключевых слов insn. Более подробную информацию см. в разделе Опции Nios II.
- ‘custom-fpu-cfg=name’
- Этот атрибут соответствует параметру командной строки -mcustom-fpu-cfg=name для выбора предварительно определенного набора пользовательских инструкций с именем name. Более подробную информацию см. в разделе Опции Nios II.
На бэкендах 386/x86_64 и PowerPC инлайнер не инлайнит функцию, имеющую разные целевые параметры, чем вызывающая функция, если у вызываемой функции нет подмножества целевых параметров вызывающей функции. Например, функция, объявленная с
target("sse3"), может инлайнить функцию сtarget("sse2"), так как-msse3подразумевает-msse2.- ‘
tiny_data- Используйте этот атрибут для H8/300H и H8S, чтобы указать, что указанная переменная должна быть помещена в раздел данных tiny. Компилятор генерирует более эффективный код для загрузки и сохранения данных в разделе tiny данных. Обратите внимание, что область tiny данных ограничена чуть менее 32 КБ данных.
trap_exit- Используйте этот атрибут для SH для
interrupt_handlerвозврата, используяtrapa, вместоrte. Этот атрибут ожидает целочисленного аргумента, указывающего номер прерывания, который следует использовать. trapa_handler- На целевых платформах SH эта функция-атрибут аналогична
interrupt_handler, но не сохраняет и не восстанавливает все регистры. unused- Этот атрибут, прикреплённый к функции, означает, что функция может быть неиспользуемой. GCC не выводит предупреждение для этой функции.
used- Этот атрибут, прикреплённый к функции, означает, что код должен быть выведен для функции, даже если кажется, что функция не ссылается. Это полезно, например, когда функция упоминается только в встроенном ассемблере.
При применении к члену-функции шаблона класса C++, атрибут также означает, что функция инстанцируется, если сам класс инстанцирован.
version_id
- Это атрибут IA-64 HP-UX, прикреплённый к глобальной переменной или функции, переименовывающий символ для включения строки версии, что позволяет реализовать версионирование на уровне функций. Заголовочные файлы системы HP-UX могут использовать версионирование на уровне функций для некоторых системных вызовов.
extern int foo () __attribute__((version_id ("20040821")));Вызовы foo отображаются на вызовы foo{20040821}.
-
visibility ("visibility_type") - Этот атрибут влияет на связь объявления, к которому он прикреплён. Поддерживаются четыре значения visibility_type: default, hidden, protected или internal visibility.
void __attribute__ ((visibility ("protected"))) f () { /* Do something. */; } int i __attribute__ ((visibility ("hidden")));Возможные значения visibility_type соответствуют настройкам видимости в ELF gABI.
- default
- Видимость по умолчанию — это нормальный случай для формата файла объекта. Это значение доступно для атрибута видимости для переопределения других параметров, которые могут изменить предполагаемую видимость сущностей.
В ELF видимость по умолчанию означает, что объявление видно другим модулям, а в динамических библиотеках — что объявленная сущность может быть переопределена.
В Darwin видимость по умолчанию означает, что объявление видно другим модулям.
Видимость по умолчанию соответствует «внешней связи» в языке.
- hidden
- Скрытая видимость указывает, что объявленная сущность имеет новый тип связи, которую мы называем «скрытой связью». Два объявления объекта со скрытой связью относятся к одному объекту, если они находятся в одном и том же динамическом объекте.
- internal
- Внутренняя видимость похожа на скрытую видимость, но с дополнительными семантиками, специфичными для процессора. Если не указано иначе psABI, GCC определяет внутреннюю видимость так, что функция никогда не вызывается из другого модуля. Сравните это со скрытыми функциями, которые, хотя и не могут быть напрямую упомянуты другими модулями, могут быть упомянуты косвенно через указатели на функции. Указав, что функция не может быть вызвана извне модуля, GCC может, например, опустить загрузку регистра PIC, поскольку известно, что вызывающая функция загрузила правильное значение.
- protected
- Защищённая видимость похожа на видимость по умолчанию, за исключением того, что она указывает, что ссылки внутри определяющего модуля привязываются к определению в этом модуле. То есть, объявленная сущность не может быть переопределена другим модулем.
Все видимости поддерживаются во многих, но не во всех, ELF-целях (поддерживаются, когда ассемблер поддерживает псевдооператор ‘
.visibility’). Видимость по умолчанию поддерживается везде. Скрытая видимость поддерживается в Darwin-целях.Атрибут видимости должен применяться только к объявлениям, которые в противном случае имели бы внешнюю связь. Атрибут должен применяться последовательно, так, чтобы одна и та же сущность не объявлялась с разными параметрами атрибута.
В C++, атрибут видимости применяется к типам, а также к функциям и объектам, потому что в C++ типы имеют связь. Класс не должен иметь большей видимости, чем его нестатические типы данных членов и базовые классы, а члены класса по умолчанию имеют видимость своего класса. Также объявление без явной видимости ограничено видимостью его типа.
В C++ вы можете помечать методы-члены и статические переменные-члены класса атрибутом видимости. Это полезно, если вы знаете, что определённый метод или статическая переменная-член должны использоваться только из одного динамического объекта; тогда вы можете пометить его как скрытый, в то время как остальная часть класса имеет видимость по умолчанию. Нужно быть осторожным, чтобы не нарушать Правило Единственного Определения; например, обычно не имеет смысла помечать встроенный метод как скрытый, не помечая весь класс как скрытый.
Объявление пространства имён C++ также может иметь атрибут видимости.
namespace nspace1 __attribute__ ((visibility ("protected"))) { /* Do something. */; }Этот атрибут применяется только к телу конкретного пространства имён, а не к другим определениям того же пространства имён; он эквивалентен использованию ‘
#pragma GCC visibility’ перед и после определения пространства имён (см. Атрибуты видимости).В C++, если аргумент шаблона имеет ограниченную видимость, это ограничение неявно распространяется на экземпляр шаблона. В противном случае экземпляры и специализации шаблонов по умолчанию имеют видимость своего шаблона.
Если и шаблон, и включающий класс имеют явную видимость, используется видимость из шаблона.
vliw- В MeP атрибут
vliwсообщает компилятору генерировать инструкции в режиме VLIW вместо режима ядра. Обратите внимание, что этот атрибут не разрешён, если не был сконфигурирован и не включён сопроцессор VLIW через параметры командной строки. warn_unused_result- Атрибут
warn_unused_resultвызывает вывод предупреждения, если вызывающий функцию с этим атрибутом не использует её возвращаемое значение. Это полезно для функций, где игнорирование результата является либо проблемой безопасности, либо всегда ошибкой, например,realloc.weakвызывает предупреждение на строке 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.
Можно указать несколько атрибутов в объявлении, разделив их запятыми внутри двойных скобок или сразу после объявления атрибута с другим объявлением атрибута.
Некоторые люди возражают против функции __attribute__, предлагая вместо неё использовать #pragma ISO C. На момент разработки __attribute__ существовало две причины, по которым это не делалось.
- Невозможно сгенерировать команды
#pragmaиз макроса. - Невозможно определить, что то же самое
#pragmaможет означать в другом компиляторе.
Эти две причины относились практически ко всем предлагаемым применениям #pragma. Фактически, использование #pragma для чего-либо было ошибкой.
Стандарт ISO C99 включает _Pragma, который теперь позволяет генерировать директивы из макросов. Кроме того, используется пространство имён #pragma GCC для GCC-специфических директив. Однако оказалось удобным использовать __attribute__ для достижения естественного прикрепления атрибутов к соответствующим объявлениям, в то время как #pragma GCC используется для конструкций, которые не естественным образом входят в грамматику. См. Директивы, принимаемые GCC.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-4.9.4/gcc/Function-Attributes.html