Spec-Zone.ru › GCC 7

6.31.1 Атрибуты общих функций

Следующие атрибуты поддерживаются на большинстве целевых платформ.

alias ("target")

Атрибут alias заставляет объявление быть выведено как псевдоним для другого символа, который должен быть указан. Например,

void __f () { /* Do something. */; }
void f () __attribute__ ((weak, alias ("__f")));

определяет ‘f’ как слабый псевдоним для ‘__f’. В C++, необходимо использовать замаскированное имя для целевой платформы. Ошибка возникает, если ‘__f’ не определено в той же единице трансляции.

Данный атрибут требует поддержки в ассемблере и объектных файлах и может быть недоступен на всех целевых платформах.

aligned (alignment)

Этот атрибут задаёт минимальное выравнивание для функции, измеряемое в байтах.

Вы не можете использовать этот атрибут для уменьшения выравнивания функции, только для его увеличения. Однако, когда вы явно задаёте выравнивание функции, это переопределяет эффект опции -falign-functions (см. Параметры оптимизации) для этой функции.

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

Атрибут aligned также может быть использован для переменных и полей (см. Атрибуты переменных).

alloc_align

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

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

Например,

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

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

alloc_size

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

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

Например,

void* my_calloc(size_t, size_t) __attribute__((alloc_size(1,2)))
void* my_realloc(void*, size_t) __attribute__((alloc_size(2)))

объявляет, что my_calloc возвращает память размером, равным произведению параметров 1 и 2, и что my_realloc возвращает память размером, равным параметру 2.

always_inline

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

artificial

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

assume_aligned

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

Например

void* my_alloc1(size_t) __attribute__((assume_aligned(16)))
void* my_alloc2(size_t) __attribute__((assume_aligned(32, 8)))

объявляет, что my_alloc1 возвращает 16-байтовый выровненный указатель, и что my_alloc2 возвращает указатель, чьё значение по модулю 32 равно 8.

bnd_instrument

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

bnd_legacy

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

cold

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

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

const

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

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

constructor
destructor
constructor (priority)
destructor (priority)

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

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

deprecated
deprecated (msg)

Атрибут deprecated приводит к появлению предупреждения, если функция используется где-либо в исходном файле. Это полезно для выявления функций, которые, как ожидается, будут удалены в будущей версии программы. Предупреждение также включает расположение объявления устаревшей функции, что позволяет пользователям легко найти дополнительную информацию о том, почему функция устарела или что им следует сделать вместо этого. Обратите внимание, что предупреждения появляются только при использовании:

int old_fn () __attribute__ ((deprecated));
int old_fn ();
int (*fn_ptr)() = old_fn;

вызывает предупреждение на строке 3, но не на строке 2. Необязательный аргумент msg, который должен быть строкой, печатается в предупреждении, если он присутствует.

Атрибут deprecated также может быть использован для переменных и типов (см. Атрибуты переменных, см. Атрибуты типов).

error ("message")
warning ("message")

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

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

externally_visible

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

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

flatten

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

format (archetype, string-index, first-to-check)

Атрибут format указывает, что функция принимает аргументы типа printf, scanf, strftime или strfmon, которые должны быть проверены на соответствие строке формата. Например, объявление:

extern int
my_printf (void *my_object, const char *my_format, ...)
      __attribute__ ((format (printf, 2, 3)));

приводит к тому, что компилятор проверяет аргументы в вызовах my_printf на соответствие строке формата стиля printf с аргументом my_format.

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

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

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

gnu_inline

Этот атрибут следует использовать с функцией, которая также объявлена с ключевым словом inline. Он указывает GCC, что функция должна обрабатываться так, как если бы она была определена в режиме gnu90, даже при компиляции в режиме C99 или gnu99.

Если функция объявлена extern, то это определение функции используется только для встраивания. Ни в коем случае функция не компилируется как самостоятельная функция, даже если вы явно получаете её адрес. Такой адрес становится внешней ссылкой, как если бы вы только объявили функцию, но не определили её. Это почти эквивалентно макросу. Способ использования заключается в размещении определения функции в заголовочном файле с этим атрибутом и размещении другой копии функции без extern в файле библиотеки. Определение в заголовочном файле приводит к тому, что большинство вызовов функции встраиваются. Если остаются какие-либо вызовы функции, они ссылаются на единственную копию в библиотеке. Обратите внимание, что два определения функций могут не быть точно одинаковыми, хотя если они не имеют одинакового эффекта, ваша программа может вести себя непредсказуемо.

В C, если функция не extern и не static, то она компилируется как самостоятельная функция, а также встраивается по возможности.

Так GCC традиционно обрабатывал функции, объявленные inline. Поскольку ISO C99 определяет иную семантику для inline, этот атрибут функции предоставляется как переходная мера и как полезная функция сама по себе. Этот атрибут доступен в GCC 4.1.3 и более поздних версиях. Он доступен, если определены один из предопределённых макросов препроцессора __GNUC_GNU_INLINE__ или __GNUC_STDC_INLINE__. См. Функция inline так же быстрая, как макрос.

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

hot

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

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

ifunc ("resolver")

Атрибут ifunc используется для маркировки функции как косвенной функции, используя расширение типа символа STT_GNU_IFUNC к стандарту ELF. Это позволяет динамически определить значение символа во время загрузки и выбрать оптимизированную версию процедуры для конкретного процессора или других характеристик системы, определённых тогда. Для использования этого атрибута сначала нужно определить доступные функции реализации и функцию-разрешитель, которая возвращает указатель на выбранную функцию реализации. Объявления функций реализации должны соответствовать API функции, которую они реализуют, объявление разрешителя должно быть функцией, возвращающей указатель на функцию, возвращающую void:

void *my_memcpy (void *dst, const void *src, size_t len)
{
  …
}

static void (*resolve_memcpy (void)) (void)
{
  return my_memcpy; // we'll just always select this routine
}

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

extern void *memcpy (void *, const void *, size_t);

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

void *memcpy (void *, const void *, size_t)
     __attribute__ ((ifunc ("resolve_memcpy")));

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

interrupt
interrupt_handler

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

leaf

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

Этот атрибут предназначен для функций библиотек для улучшения анализа потока данных. Компилятор принимает подсказку о том, что любые данные, не выходящие за пределы текущей единицы компиляции, не могут использоваться или изменяться функцией-листом. Например, функция sin — функция-лист, но qsort — нет.

Обратите внимание, что функции-листы могут косвенно запускать обработчик сигналов, определенный в текущей единице компиляции, который использует статические переменные. Аналогично, при активном ленивом разрешении символов функции-листы могут вызывать косвенные функции, функция разрешения или функция реализации которых определены в текущей единице компиляции и используют статические переменные. Нет стандартного способа написания такого обработчика сигналов, функции разрешения или функции реализации, и все, что вы можете сделать, это удалить атрибут leaf или пометить все такие статические переменные volatile. Наконец, для систем на основе ELF, которые поддерживают интерпозицию символов, следует позаботиться о том, чтобы функции, определенные в текущей единице компиляции, не неожиданно интерпозировали другие символы на основе определенного стандартного режима и определенных макросов проверки функций; в противном случае будет добавлен нежелательный обратный вызов.

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

malloc

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

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

no_icf

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

no_instrument_function

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

no_profile_instrument_function

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

no_reorder

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

no_sanitize_address
no_address_safety_analysis

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

no_sanitize_thread

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

no_sanitize_undefined

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

no_split_stack

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

no_stack_limit

Этот атрибут локально переопределяет опции командной строки -fstack-limit-register и -fstack-limit-symbol; он имеет эффект отключения проверки лимитов стека в функции, к которой он применён.

noclone

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

noinline

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

asm ("");

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

nonnull (arg-index, …)

Атрибут nonnull указывает, что некоторые параметры функций должны быть указателями, отличными от нуля. Например, объявление:

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

приводит к тому, что компилятор проверяет, что в вызовах my_memcpy, аргументы dest и src не равны нулю. Если компилятор определяет, что в аргументе с меткой "не равно нулю" передан указатель с нулевым значением, и опция -Wnonnull включена, выводится предупреждение. Компилятор также может выбрать оптимизацию, основываясь на знаниях о том, что определённые аргументы функции никогда не будут равны нулю.

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

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

Атрибут noplt является аналогом опции -fno-plt. Вызовы функций, помеченных этим атрибутом в позиционно-независимом коде, не используют PLT.

/* Externally defined function foo.  */
int foo () __attribute__ ((noplt));

int
main (/* … */)
{
  /* … */
  foo ();
  /* … */
}

Атрибут noplt для функции foo сообщает компилятору, что функция foo определена внешним образом и что вызов foo должен избегать PLT в позиционно-независимом коде.

В позиционно-зависимом коде некоторые цели также преобразуют вызовы функций, которые помечены как не использующие PLT, в использование GOT вместо этого.

noreturn

Некоторые стандартные библиотечные функции, такие как abort и exit, не могут вернуть значение. GCC знает об этом автоматически. Некоторые программы определяют свои собственные функции, которые никогда не возвращают значение. Вы можете объявить их noreturn , чтобы сообщить компилятору об этом факте. Например,

void fatal () __attribute__ ((noreturn));

void
fatal (/* … */)
{
  /* … */ /* Print error message. */ /* … */
  exit (1);
}

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

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

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

Не имеет смысла, чтобы функция noreturn имела тип возвращаемого значения, отличный от void.

nothrow

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

optimize

Атрибут optimize используется для указания того, что функция должна компилироваться с различными опциями оптимизации, чем указано в командной строке. Аргументы могут быть либо числами, либо строками. Числа предполагаются уровнем оптимизации. Строки, начинающиеся с O, предполагаются опцией оптимизации, в то время как другие опции предполагаются с префиксом -f. Вы также можете использовать директиву «#pragma GCC optimize» для установки опций оптимизации, влияющих на более чем одну функцию. Смотрите Функционально-специфические опции для получения подробной информации о директиве «#pragma GCC optimize».

Этот атрибут следует использовать только в отладочных целях. Он не подходит для использования в производственном коде.

pure

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

int square (int) __attribute__ ((pure));

говорит, что гипотетическая функция square может вызываться меньше раз, чем указано в программе.

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

returns_nonnull

Атрибут returns_nonnull указывает, что возвращаемое значение функции должно быть указателем, отличным от нуля. Например, объявление:

extern void *
mymalloc (size_t len) __attribute__((returns_nonnull));

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

returns_twice

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

section ("section-name")

Обычно компилятор размещает сгенерированный код в секции text. Однако иногда необходимы дополнительные секции или требуется, чтобы определенные функции находились в специальных секциях. Атрибут section указывает, что функция находится в конкретной секции. Например, объявление:

extern void foobar (void) __attribute__ ((section ("bar")));

размещает функцию foobar в секции bar.

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

sentinel

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

__attribute__ ((sentinel))
is equivalent to
__attribute__ ((sentinel(0)))

Атрибут автоматически устанавливается с позицией 0 для встроенных функций execl и execlp. Для встроенной функции execle атрибут устанавливается с позицией 1.

Действительный NULL в этом контексте определяется как ноль с любым типом указателя. Если ваша система определяет макрос NULL с целочисленным типом, вам необходимо добавить явное приведение типа. GCC заменяет stddef.h копией, которая соответствующим образом переопределяет NULL.

Предупреждения о пропущенных или неправильных sentinel включены с помощью -Wformat.

simd
simd("mask")

Этот атрибут позволяет создать одну или несколько версий функций, которые могут обрабатывать несколько аргументов с помощью инструкций SIMD из одного вызова. Указание этого атрибута позволяет компилятору предполагать, что такие версии доступны на этапе компоновки (приведены в той же или другой единице трансляции). Сгенерированные версии зависят от целевой платформы и описаны в соответствующем документе Vector ABI. Для целевой платформы x86_64 этот документ можно найти здесь.

Необязательный аргумент mask может иметь значение notinbranch или inbranch, и соответственно инструктирует компилятор генерировать не-маскированные или маскированные клоны. По умолчанию генерируются все клоны.

Атрибут не должен использоваться вместе с атрибутом Cilk Plus vector для той же функции.

Если атрибут указан, а #pragma omp declare simd присутствует в объявлении, и переключатель -fopenmp или -fopenmp-simd указан, то атрибут игнорируется.

stack_protect

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

target (options)

Несколько целевых back-end реализуют атрибут target для указания того, что функция должна компилироваться с различными параметрами целевой платформы, отличными от указанных в командной строке. Это можно использовать, например, для компиляции функций с другой ISA (архитектурой набора инструкций), отличной от стандартной. Вы также можете использовать псевдоним #pragma GCC target для установки более чем одной функции для компиляции со специфическими параметрами целевой платформы. Подробнее о псевдониме #pragma GCC target см. в разделе Function Specific Option Pragmas.

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

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

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

Поддерживаемые параметры специфичны для каждой целевой платформы; см. x86 Function Attributes, PowerPC Function Attributes, ARM Function Attributes и Nios II Function Attributes для получения подробной информации.

target_clones (options)

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

Например, на x86 вы можете скомпилировать функцию с target_clones("sse4.1,avx"). GCC создает два клонированных варианта функции: один скомпилирован с -msse4.1, другой — с -mavx. Также создается функция-резольвер (см. атрибут ifunc выше), которая динамически выбирает клон, подходящий для текущей архитектуры.

unused

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

used

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

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

visibility ("visibility_type")

Этот атрибут влияет на связь объявления, к которому он прикреплен. Его можно применять к переменным (см. Общие атрибуты переменных) и типам (см. Общие атрибуты типов), а также к функциям.

Поддерживаются четыре значения visibility_type: default, hidden, protected или internal visibility.

void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }
int i __attribute__ ((visibility ("hidden")));

Возможные значения visibility_type соответствуют настройкам видимости в ELF gABI.

default

Видимость по умолчанию — это нормальный случай для формата файла объекта. Это значение доступно для атрибута видимости, чтобы переопределить другие параметры, которые могут изменить предполагаемую видимость сущностей.

В ELF видимость по умолчанию означает, что объявление видно другим модулям и, в разделяемых библиотеках, означает, что объявленная сущность может быть переопределена.

В Darwin видимость по умолчанию означает, что объявление видно другим модулям.

Видимость по умолчанию соответствует «внешней связи» в языке.

hidden

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

internal

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

protected

Видимость protected подобна видимости по умолчанию, за исключением того, что она указывает, что ссылки внутри определяющего модуля привязываются к определению в этом модуле. То есть, объявленная сущность не может быть переопределена другим модулем.

Все видимости поддерживаются во многих, но не во всех, ELF-целях (поддерживаются, когда ассемблер поддерживает псевдооператор ‘.visibility’). Видимость по умолчанию поддерживается везде. Скрытая видимость поддерживается в целях Darwin.

Атрибут видимости должен применяться только к объявлениям, которые в противном случае имели бы внешнюю связь. Атрибут должен применяться последовательно, так чтобы одна и та же сущность не объявлялась с разными настройками атрибута.

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

В C++, вы можете пометить методы членов и статические переменные членов класса атрибутом видимости. Это полезно, если вы знаете, что определённый метод или статическая переменная члена должны использоваться только из одного разделяемого объекта; затем вы можете пометить его как скрытый, в то время как остальная часть класса имеет видимость по умолчанию. Следует соблюдать осторожность, чтобы избежать нарушения правила одного определения; например, обычно не имеет смысла помечать встроенный метод как скрытый без пометки всего класса как скрытого.

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

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

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

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

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

warn_unused_result

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

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

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

weak

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

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.

Далее: Атрибуты функций AArch64, Назад: Атрибуты функций [Содержание][Индекс]

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

Spec-Zone.ru

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