Spec-Zone.ru › GCC 5

6.31 Объявление атрибутов функций

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

Ключевое слово __attribute__ позволяет вам указывать специальные атрибуты при объявлении. Это ключевое слово следует за указанием атрибута в двойных скобках. Следующие атрибуты в настоящее время определены для функций на всех целевых системах: aligned, alloc_size, alloc_align, assume_aligned, noreturn, returns_twice, noinline, noclone, no_icf, 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_thread, no_sanitize_undefined, no_reorder, bnd_legacy, bnd_instrument, stack_protect, 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 возвращает память размером, равным произведению параметра 1 и 2, и что my_realloc возвращает память размером, равным параметру 2.

alloc_align

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

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

Например,

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

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

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__. См. Функция Inline так же быстрая, как макрос.

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

artificial

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

bank_switch

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

flatten

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

error ("message")

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

warning ("message")

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

cdecl

На целевых x86-32, атрибут cdecl заставляет компилятор считать, что вызывающая функция удаляет из стека пространство, используемое для передачи аргументов. Это полезно для переопределения эффектов переключателя -mrtd.

const

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

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

constructor
destructor
constructor (priority)
destructor (priority)

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

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

Эти атрибуты в настоящее время не реализованы для Objective-C.

deprecated
deprecated (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. Так как это может привести к увеличению размера файла объекта, вы можете использовать -fno-keep-inline-dllexport, который сообщает GCC игнорировать атрибут для встроенных функций, если вместо этого не используется флаг -fkeep-inline-functions.

Атрибут игнорируется для неопределённых символов.

При применении к 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 с помощью thunk.

На целевой платформе SH Symbian OS атрибут dllimport также имеет другое влияние — он может привести к экспорту vtable и информации о типе во время выполнения для класса. Это происходит, когда класс имеет импортированный конструктор или не встроенную, не чистую виртуальную функцию и, в любом из этих двух случаев, класс также имеет встроенный конструктор или деструктор и имеет ключевую функцию, определённую в текущей единице трансляции.

Для целевых платформ Microsoft Windows использование атрибута dllimport для функций не является необходимым, но обеспечивает небольшое преимущество в производительности, устраняя thunk в DLL. Использование атрибута dllimport для импортированных переменных можно избежать, передав переключатель --enable-auto-import линкеру GNU. Как и для функций, использование атрибута для переменной устраняет thunk в DLL.

Одним из недостатков использования этого атрибута является то, что указатель на переменную, помеченную как dllimport, не может быть использован как постоянный адрес. Однако указатель на функцию с атрибутом dllimport может быть использован в качестве константы-инициализатора; в этом случае, ссылается на адрес функции-заглушки в библиотеке импорта. На целевых платформах Microsoft Windows атрибут можно отключить для функций, установив флаг -mnop-fun-dllimport.

exception

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

exception_handler

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

externally_visible

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

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

far

На целевых платформах MeP это заставляет компилятор использовать соглашение о вызовах, предполагающее, что вызываемая функция слишком далеко для встроенных режимов адресации.

fast_interrupt

Используйте этот атрибут на портах M32C и RX для указания того, что указанная функция является быстрым обработчиком прерываний. Это то же самое, что и атрибут interrupt, за исключением того, что freit используется для возврата вместо reit.

fastcall

На x86-32 целевых платформах атрибут fastcall заставляет компилятор передавать первый аргумент (если он целого типа) в регистр ECX, а второй аргумент (если он целого типа) в регистр EDX. Последующие и другие аргументы с другими типами передаются в стеке. Вызываемая функция извлекает аргументы из стека. Если количество аргументов является переменным, все аргументы помещаются в стек.

thiscall

На x86-32 целевых платформах атрибут thiscall заставляет компилятор передавать первый аргумент (если он целого типа) в регистр ECX. Последующие и другие аргументы с другими типами передаются в стеке. Вызываемая функция извлекает аргументы из стека. Если количество аргументов является переменным, все аргументы помещаются в стек. Атрибут thiscall предназначен для функций-членов C++ (не статических). В качестве расширения GCC это соглашение о вызовах может использоваться для функций 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 на соответствие строке формата стиля printf my_format.

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

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

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

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

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

format_arg (string-index)

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

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).

В следующем примере 2 байта экономится для каждого вызова функции foo.

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

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

interrupt

Используйте этот атрибут для портов ARC, ARM, AVR, CR16, Epiphany, M32C, M32R/D, m68k, MeP, MIPS, MSP430, NDS32, RL78, RX, Visium и 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).

На целях RX вы можете указать один или несколько номеров векторов в качестве аргументов атрибута, а также указать имя альтернативной таблицы. Параметры обрабатываются последовательно, поэтому один обработчик может быть назначен нескольким записям в нескольких таблицах. Также можно передать магическую строку "$default", которая заставит функцию использоваться для всех незаполненных ячеек в текущей таблице.

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

void __attribute__ ((interrupt (5))) txd1_handler ();

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

void __attribute__ ((interrupt (RXD1_VECT,RXD2_VECT,"dct","$default")))
	txd1_handler ();
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

Этот атрибут указывает функцию, которая должна быть помещена в SRAM инструкций L1. Функция помещается в определенный раздел с именем .l1.text. При -mfdpic вызовы функций с такой функцией в качестве вызываемой или вызывающей функции используют встроенный PLT.

l2

На Blackfin этот атрибут указывает функцию, которая должна быть помещена в SRAM L2. Функция помещается в определенный раздел с именем .l1.text. При -mfdpic вызывающие функции таких функций используют встроенный PLT.

leaf

Вызовы внешних функций с этим атрибутом должны возвращаться в текущий блок компиляции только с помощью return или обработки исключений. В частности, функции-листья не могут вызывать функции обратного вызова, переданные им из текущего блока компиляции, или напрямую вызывать функции, экспортируемые блоком, или использовать 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 и PowerPC атрибут longcall указывает, что функция может находиться далеко от места вызова и требует другой (более дорогостоящей) последовательности вызова. Атрибут shortcall указывает, что функция всегда достаточно близка для использования более короткой последовательности вызова. Эти атрибуты переопределяют переключатель -mlongcall и, в RS/6000 и PowerPC, настройку #pragma longcall.

См. Параметры RS/6000 и PowerPC для получения дополнительной информации о необходимости длинных вызовов.

long_call
near
far

Эти атрибуты определяют, как конкретная функция вызывается на MIPS. Атрибуты переопределяют командно-строковый переключатель -mlong-calls (см. Параметры MIPS). Атрибуты long_call и far являются синонимами и заставляют компилятор всегда вызывать функцию, сначала загрузив её адрес в регистр, а затем используя содержимое этого регистра. Атрибут near имеет обратный эффект; он указывает, что вызовы без PIC должны выполняться с использованием более эффективной инструкции jal.

malloc

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

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

mips16
nomips16

На MIPS-целевых платформах вы можете использовать атрибуты функций mips16 и nomips16 для локального выбора или отключения генерации кода MIPS16. Функция с атрибутом mips16 генерируется как код MIPS16, в то время как генерация кода MIPS16 отключена для функций с атрибутом nomips16. Эти атрибуты переопределяют опции -mips16 и -mno-mips16 в командной строке (см. Параметры MIPS).

При компиляции файлов, содержащих смешанный код MIPS16 и не-MIPS16, препроцессорная переменная __mips16 отражает установку в командной строке, а не в отдельных функциях. Смешанный код MIPS16 и не-MIPS16 может плохо взаимодействовать с некоторыми расширениями GCC, такими как __builtin_apply (см. Создание вызовов).

micromips, MIPS
nomicromips, MIPS

На MIPS-целевых платформах вы можете использовать атрибуты функций micromips и nomicromips для локального выбора или отключения генерации микроMIPS-кода. Функция с атрибутом micromips генерируется как микроMIPS-код, а генерация микроMIPS-кода отключена для функций с атрибутом nomicromips. Эти атрибуты переопределяют опции -mmicromips и -mno-micromips в командной строке (см. Параметры MIPS).

При компиляции файлов, содержащих смешанный микроMIPS и не-микроMIPS-код, препроцессорная переменная __mips_micromips отражает установку в командной строке, а не в отдельных функциях. Смешанный микроMIPS и не-микроMIPS-код может плохо взаимодействовать с некоторыми расширениями 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).

ms_abi
sysv_abi

На 32- и 64-битных x86-целевых платформах вы можете использовать атрибут 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)

На x86-32 целевых платформах вы можете использовать этот атрибут для управления тем, как агрегаты возвращаются в памяти. Если вызывающая сторона отвечает за извлечение скрытого указателя вместе с остальными аргументами, установите number равным нулю. Если вызываемая сторона отвечает за извлечение скрытого указателя, установите number равным единице.

По умолчанию x86-32 ABI предполагает, что вызываемая сторона извлекает стек для скрытого указателя. Однако на x86-32 целевых платформах Microsoft Windows компилятор предполагает, что вызывающая сторона извлекает стек для скрытого указателя.

ms_hook_prologue

На 32- и 64-битных x86 целевых платформах вы можете использовать этот атрибут функции, чтобы заставить GCC сгенерировать пролог функции «горячей подмены», используемый в функциях Win32 API в 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 инструкции (см. Базовый ассемблер). Хотя использование расширенных asm или смешанных базовых asm и C-кодов может показаться работающим, на них нельзя полагаться, и они не поддерживаются.

near

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

nesting

Используйте этот атрибут вместе с interrupt_handler, exception_handler или nmi_handler, чтобы указать, что код входа в функцию должен разрешить вложенные прерывания или исключения.

nmi_handler

Используйте этот атрибут на процессорах Blackfin, чтобы указать, что указанная функция является обработчиком NMI. Компилятор генерирует последовательности входа и выхода из функции, подходящие для использования в обработчике NMI, когда этот атрибут присутствует.

nocompression

На MIPS-целевых платформах вы можете использовать атрибут функции nocompression, чтобы локально отключить генерацию кода MIPS16 и microMIPS. Этот атрибут переопределяет опции -mips16 и -mmicromips в командной строке (см. MIPS Options).

no_instrument_function

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

no_split_stack

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

stack_protect

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

noinline

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

asm ("");

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

noclone

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

no_icf

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

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

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

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.

nothrow

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

nosave_low_regs

Используйте этот атрибут на целевых платформах SH, чтобы указать, что функция interrupt_handler не должна сохранять и восстанавливать регистры R0..R7. Это можно использовать на целевых платформах SH3* и SH4*, которые имеют второй банк регистров R0..R7 для нерекурсивных обработчиков прерываний.

optimize

Атрибут optimize используется для указания того, что функция должна компилироваться с различными параметрами оптимизации, чем указано в командной строке. Аргументы могут быть числами или строками. Числа предполагаются как уровень оптимизации. Строки, начинающиеся с O, предполагаются как опция оптимизации, в то время как другие опции предполагаются как используемые с префиксом -f. Вы также можете использовать директиву ‘#pragma GCC optimize’ для установки параметров оптимизации, которые влияют на более чем одну функцию. Подробности о директиве ‘#pragma GCC optimize’ см. в Function Specific Option Pragmas.

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

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

hot

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

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

cold

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

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

no_sanitize_address
no_address_safety_analysis

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

no_sanitize_thread

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

no_sanitize_undefined

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

bnd_legacy

Атрибут bnd_legacy для функций используется для информирования компилятора о том, что функция не должна инструментироваться при компиляции с опцией -fcheck-pointer-bounds.

bnd_instrument

Атрибут bnd_instrument для функций используется для информирования компилятора о том, что функция должна быть инструментирована при компиляции с опцией -fchkp-instrument-marked-only.

regparm (number)

На целевых платформах x86-32 атрибут regparm заставляет компилятор передавать аргументы с номера one до number (если они целочисленного типа) в регистрах EAX, EDX и ECX вместо стека. Функции, принимающие переменное число аргументов, по-прежнему передают все свои аргументы в стеке.

Обратите внимание, что на некоторых системах ELF этот атрибут непригоден для глобальных функций в общих библиотеках с отложенной привязкой (что является значением по умолчанию). Отложенная привязка отправляет первый вызов через код разрешения в загрузчике, который может предположить, что EAX, EDX и ECX могут быть перезаписаны в соответствии со стандартными соглашениями о вызовах. Solaris 8 затронут этой проблемой. Считается, что системы с версией GNU C Library 2.1 или выше и FreeBSD безопасны, так как загрузчики в них сохраняют EAX, EDX и ECX. (Отложенную привязку можно отключить с помощью компоновщика или загрузчика, если это необходимо, чтобы избежать проблемы.)

reset

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

nmi

Предоставьте пользовательскую функцию для обработки исключения NMI.

warm

Предоставьте пользовательскую функцию для обработки исключения тёплого сброса.

sseregparm

На целевых платформах x86-32 с поддержкой SSE атрибут sseregparm заставляет компилятор передавать до 3 аргументов с плавающей точкой в регистрах SSE вместо стека. Функции, принимающие переменное число аргументов, по-прежнему передают все свои аргументы с плавающей точкой в стеке.

force_align_arg_pointer

На целевых платформах x86 атрибут force_align_arg_pointer может применяться к отдельным определениям функций, генерируя альтернативный пролог и эпилог, которые при необходимости перестраивают стек во время выполнения. Это поддерживает смешение устаревшего кода, работающего со стеком с выравниванием на 4 байта, с современным кодом, использующим 16-байтовый стек для совместимости SSE.

renesas

На целевых платформах SH этот атрибут указывает, что функция или структура соответствует ABI Renesas.

resbank

На целевой платформе SH2A этот атрибут позволяет использовать высокоскоростное сохранение и восстановление регистров с использованием банка регистров для interrupt_handler процедур. Сохранение в банк выполняется автоматически после того, как ЦП принимает прерывание, использующее банк регистров.

Девятнадцать 32-битных регистров, составляющих общий регистр R0 до R14, регистр управления GBR и системные регистры MACH, MACL и PR, а также смещение адреса таблицы векторов сохраняются в банке регистров. Банки регистров стекируются в порядке «первый вошёл, последний вышел» (FILO). Восстановление из банка выполняется путём выдачи инструкции RESBANK.

returns_twice

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

saveall

Используйте этот атрибут на платформах Blackfin, H8/300, H8/300H и H8S, чтобы указать, что все регистры, кроме указателя стека, должны сохраняться в прологе, независимо от того, используются ли они или нет.

save_volatiles

Используйте этот атрибут на платформе MicroBlaze для обозначения функции как обработчика прерываний. Все регистры, помеченные как volatile, (в дополнение к неvolatile) сохраняются в прологе функции. Если функция является лиственной функцией, сохраняются только регистры volatile, используемые функцией. Генерируется обычное возвращение из функции, а не возврат из прерывания.

break_handler

Используйте этот атрибут на портах MicroBlaze, чтобы указать, что указанная функция является обработчиком break. При наличии этого атрибута компилятор генерирует последовательности входа и выхода из функции, подходящие для использования в обработчике break. Возврат из break_handler выполняется через rtbd вместо rtsd.

void f () __attribute__ ((break_handler));
section ("section-name")

Обычно компилятор помещает сгенерированный код в секцию 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.

shortcall

См. longcall.

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

В целевых системах x86-32 атрибут stdcall заставляет компилятор предполагать, что вызываемая функция очищает пространство стека, используемое для передачи аргументов, если только она не принимает переменное число аргументов.

syscall_linkage

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

target

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

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

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

Вы можете использовать несколько строк для указания нескольких параметров или разделить параметры запятой (‘,’).

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

На x86 разрешены следующие параметры:

‘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.

‘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’

Генерировать код, использующий (не использующий) инструкцию перемещения из регистра состояния (condition register field) реализованную на процессоре 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’

Предполагать (не предполагать), что инструкции оценки обратного значения обеспечивают более точные оценки, чем это предписывает PowerPC ABI.

‘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 Options для получения дополнительной информации.

‘custom-fpu-cfg=name’

Этот атрибут соответствует параметру командной строки -mcustom-fpu-cfg=name для выбора предопределённого набора пользовательских инструкций с именем name. См. Nios II Options для получения дополнительной информации.

В x86 и PowerPC бэкендах инлайнер не инлайнит функцию, которая имеет другие опции целевой платформы, чем вызывающая функция, если только функция-вызываемая не имеет подмножества опций целевой платформы вызывающей функции. Например, функция, объявленная с target("sse3"), может инлайнить функцию с target("sse2"), так как -msse3 подразумевает -msse2.

trap_exit

Используйте этот атрибут на SH для interrupt_handler возврата с использованием trapa вместо rte. Этот атрибут ожидает целочисленное значение, указывающее номер прерывания, которое будет использоваться.

trapa_handler

На целевых платформах SH этот атрибут функции похож на interrupt_handler, но он не сохраняет и не восстанавливает все регистры.

unused

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

used

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

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

vector

Этот атрибут RX похож на атрибут interrupt, включая его параметры, но не делает функцию типом функции-обработчика прерываний (то есть сохраняет обычный C вызов ABI). См. атрибут interrupt для описания его аргументов.

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.

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++, вы можете помечать методы членов и статические переменные членов класса атрибутом видимости. Это полезно, если вы знаете, что определённый метод или статическая переменная члена должны использоваться только из одного разделяемого объекта; тогда вы можете пометить его как hidden, а остальная часть класса имеет видимость по умолчанию. Следует быть внимательным, чтобы избежать нарушения правила единого определения; например, обычно не имеет смысла помечать внутренний метод как hidden без пометки всего класса как hidden.

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

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

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

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

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

vliw

В MeP атрибут vliw сообщает компилятору выводить инструкции в режиме VLIW, а не в режиме ядра. Обратите внимание, что этот атрибут недопустим, если не сконфигурирован и не активирован VLIW-копроцессор с помощью параметров командной строки.

warn_unused_result

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

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

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

weak

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

weakref
weakref ("target")

Атрибут weakref помечает объявление как слабую ссылку. Без аргументов оно должно сопровождаться атрибутом alias, называющим целевой символ. Дополнительно, target можно указать как аргумент в weakref. В любом случае, 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__ существовало две причины для этого не делать.

  1. Невозможно сгенерировать команды #pragma из макроса.
  2. Невозможно предугадать, что означает тот же #pragma в другом компиляторе.

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

Стандарт ISO C99 включает _Pragma, который теперь позволяет генерировать директивы из макросов. Кроме того, теперь используется пространство имён #pragma GCC для GCC-специфических директив. Однако, оказалось удобным использовать __attribute__ для естественного прикрепления атрибутов к соответствующим объявлениям, тогда как #pragma GCC полезно для конструкций, которые не являются естественной частью грамматики. См. Директивы, поддерживаемые GCC.

Далее: Атрибуты меток, Предыдущее: Смешанные объявления, Вверх: Расширения языка C [Оглавление][Индекс]

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

Spec-Zone.ru

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