Spec-Zone.ru › GCC 10

Следующее: Атрибуты функций AArch64, Вверх: Объявление атрибутов функций [Оглавление][Индекс]

6.33.1 Общие атрибуты функций ¶

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

access
access (access-mode, ref-index)
access (access-mode, ref-index, size-index)

Атрибут access позволяет обнаруживать некорректные или небезопасные обращения функций, к которым он применяется, или их вызывающих функций, а также обращения только для записи к объектам, которые никогда не читаются. Такие обращения могут диагностироваться предупреждениями, такими как -Wstringop-overflow, -Wuninitialized, -Wunused и другими.

Атрибут access указывает, что функция, к аргументам которой по ссылке применяется данный атрибут, обращается к объекту по ссылке в соответствии с access-mode. Аргумент access-mode является обязательным и должен быть одним из трех имен: read_only, read_write, или write_only. Остальные два — позиционные аргументы.

Обязательный позиционный аргумент ref-index обозначает аргумент функции типа указатель (или в C++, ссылка), который подвергается обработке атрибутом доступа. Один и тот же аргумент указателя может быть использован не более чем одним атрибутом access.

Необязательный позиционный аргумент size-index обозначает аргумент функции целочисленного типа, который задает максимальный размер доступа. Размер представляет собой количество элементов типа, на который указывает ref-index, или количество байтов, когда тип указателя является void*. Если аргумент size-index не указан, аргумент указателя должен быть либо нулевым, либо указывать на область памяти, которая должным образом выровнена и достаточно велика для по крайней мере одного объекта указанного типа (это подразумевает, что указатель за границами выделенной области памяти не является допустимым аргументом). Фактический размер доступа может быть меньше, но не больше.

Режим доступа read_only указывает, что указатель, к которому он применяется, используется для чтения объекта, но не для записи в него. Если аргумент, определяющий размер доступа, указанный аргументом size-index, не равен нулю, то ссылаемый объект должен быть инициализирован. Этот режим подразумевает более сильную гарантию, чем квалификатор const, который, при преобразовании от указателя, не предотвращает модификацию объекта, на который он указывает. Примеры использования режима доступа read_only — это аргумент функции puts, или второй и третий аргументы функции memcpy.

__attribute__ ((access (read_only, 1))) int puts (const char*);
__attribute__ ((access (read_only, 1, 2))) void* memcpy (void*, const void*, size_t);

Режим доступа read_write применяется к аргументам типов указателей без квалификатора const. Он указывает, что указатель, к которому он применяется, используется как для чтения, так и для записи в ссылаемый объект. Если аргумент, определяющий размер доступа, указанный аргументом size-index, не равен нулю, то ссылаемый объект должен быть инициализирован. Пример использования режима доступа read_write — первый аргумент функции strcat.

__attribute__ ((access (read_write, 1), access (read_only, 2))) char* strcat (char*, const char*);

Режим доступа write_only применяется к аргументам типов указателей без квалификатора const. Он указывает, что указатель, к которому он применяется, используется для записи в ссылаемый объект, но не для чтения из него. Объект, на который указывает указатель, не обязан быть инициализирован. Пример использования режима доступа write_only — первый аргумент функции strcpy, или первые два аргумента функции fgets.

__attribute__ ((access (write_only, 1), access (read_only, 2))) char* strcpy (char*, const char*);
__attribute__ ((access (write_only, 1, 2), access (read_write, 3))) int fgets (char*, int, FILE*);
alias ("target")

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

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

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

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

aligned
aligned (alignment)

Атрибут aligned задает минимальное выравнивание первого инструкции функции в байтах. При использовании, alignment должен быть целым константой, являющейся степенью двойки. Если аргумент alignment не указан, то предполагается идеальное выравнивание для целевой платформы. Оператор __alignof__ используется для определения этого значения (см. Определение выравнивания функций, типов или переменных). Атрибут не имеет эффекта, если определение функции не приведено в том же модуле трансляции.

Атрибут не может быть использован для уменьшения выравнивания функции, ранее объявленной с более строгим выравниванием; он может быть только использован для его увеличения. Попытки сделать обратное диагностируются. Некоторые целевые платформы задают минимальное значение по умолчанию для выравнивания функций, которое больше 1. На таких платформах, указание менее строгого выравнивания игнорируется. Использование данного атрибута переопределяет действие опции -falign-functions (см. Параметры, которые управляют оптимизацией) для этой функции.

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

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

alloc_align (position)

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

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

Например,

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

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

alloc_size (position)
alloc_size (position-1, position-2)

Атрибут alloc_size может быть применён к функции, которая возвращает указатель и принимает по меньшей мере один аргумент целого или перечислимого типа. Он указывает, что возвращаемый указатель указывает на память, размер которой задан аргументом функции в position-1, или произведением аргументов в position-1 и position-2. Значимые размеры — положительные значения, меньшие PTRDIFF_MAX. GCC использует эту информацию, чтобы улучшить результаты __builtin_object_size.

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

Например,

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

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

always_inline

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

artificial

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

assume_aligned (alignment)
assume_aligned (alignment, offset)

Атрибут assume_aligned может быть применён к функции, возвращающей указатель. Он указывает, что возвращаемый указатель выровнен на границе, заданной alignment. Если у атрибута два аргумента, второй аргумент — это смещение offset. Значимые значения alignment — степени двойки, большие единицы. Значимые значения offset — больше нуля и меньше alignment.

Например,

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

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

cold

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

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

const

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

Например,

int square (int) __attribute__ ((const));

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

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

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

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

constructor
destructor
constructor (priority)
destructor (priority)

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

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

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

copy
copy (function)

Атрибут copy применяет набор атрибутов, с которыми объявлена функция function, к объявлению функции, к которой применяется атрибут. Атрибут предназначен для библиотек, которые определяют псевдонимы или функции разрешения, которые должны указывать тот же набор атрибутов, что и их целевые объекты. Атрибут copy может использоваться с функциями, переменными или типами. Однако тип символа, к которому применяется атрибут (функция или переменная), должен соответствовать типу символа, на который ссылается аргумент. Атрибут copy копирует только синтаксические и семантические атрибуты, но не атрибуты, влияющие на связи или видимость символа, такие как alias, visibility, или weak. Атрибуты deprecated и target_clones также не копируются. См. Общие атрибуты типов. См. Общие атрибуты переменных.

Например, макрос StrongAlias ниже использует атрибуты alias и copy для определения псевдонима, названного alloc, для функции allocate, объявленной с атрибутами alloc_size, malloc и nothrow. Благодаря оператору __typeof__ псевдоним имеет тот же тип, что и целевая функция. В результате атрибута copy псевдоним также разделяет те же атрибуты, что и целевой объект.

#define StrongAlias(TargetFunc, AliasDecl)  \
  extern __typeof__ (TargetFunc) AliasDecl  \
    __attribute__ ((alias (#TargetFunc), copy (TargetFunc)));

extern __attribute__ ((alloc_size (1), malloc, nothrow))
  void* allocate (size_t);
StrongAlias (allocate, alloc);
deprecated
deprecated (msg)

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

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

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

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

Сообщение, прикреплённое к атрибуту, зависит от настройки опции -fmessage-length.

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

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

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

externally_visible

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

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

flatten

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

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

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

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

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

Параметр archetype определяет, как интерпретируется строка формата, и должен быть printf, scanf, strftime, gnu_printf, gnu_scanf, gnu_strftime или strfmon. (Можно также использовать __printf__, __scanf__, __strftime__ или __strfmon__. На целевых платформах MinGW также присутствуют ms_printf, ms_scanf, и ms_strftime. Значения archetype, такие как printf, относятся к форматам, поддерживаемым системной библиотекой C Runtime, в то время как значения, начинающиеся с «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 (при этом оставшиеся аргументы функции формата остаются такими же, как и для исходной строки). Несколько атрибутов format_arg могут быть применены к одной функции, каждый из которых определяет отдельный параметр как строку формата. Например, объявление:

extern char *
my_dgettext (char *my_domain, const char *my_format)
      __attribute__ ((format_arg (2)));

приводит к тому, что компилятор проверяет аргументы в вызовах функции типа printf, scanf, strftime или strfmon, строка формата которой является вызовом функции my_dgettext, на соответствие аргументу строки формата my_format. Если атрибут format_arg не был указан, компилятор мог бы только сказать, что аргумент строки формата не является константой; это сгенерировало бы предупреждение при использовании -Wformat-nonliteral, но вызовы не могли бы быть проверены без атрибута.

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

Параметр string-index указывает, какой аргумент является аргументом строки формата (начиная с одного). Поскольку у нестатических методов C++ есть неявный аргумент this, аргументы таких методов должны учитываться с позиции два.

Атрибут format_arg позволяет идентифицировать собственные функции, модифицирующие строки формата, так что GCC может проверять вызовы функций типа printf, scanf, strftime или strfmon, операндами которых является вызов одной из собственных функций. Компилятор всегда обрабатывает gettext, dgettext, и dcgettext таким образом, за исключением случаев, когда запрошена строгая поддержка ISO C с помощью -ansi или соответствующего параметра -std, или используется -ffreestanding или -fno-builtin. См. Параметры, определяющие диалект C.

Для диалектов Objective-C атрибут format-arg может ссылаться на NSString ссылку для совместимости с атрибутом format выше.

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

gnu_inline

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

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

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

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

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

hot

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

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

ifunc ("resolver")

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

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

static void * (*resolve_memcpy (void))(void *, const void *, size_t)
{
  return my_memcpy; // we will just always select this routine
}

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

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

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

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

В C++, атрибут ifunc принимает строку, которая является искажённым именем функции-разрешителя. Функция-разрешитель C++ для нестатического метода класса C должна быть объявлена так, чтобы возвращать указатель на внеклассовую функцию, принимающую в качестве первого аргумента указатель на C, а затем те же аргументы, что и функция реализации. G++ проверяет сигнатуры обеих функций и выводит предупреждение -Wattribute-alias в случае несоответствия. Чтобы подавить предупреждение о необходимости приведения типа указателя на член функции реализации к типу соответствующей внеклассовой функции, используйте опцию -Wno-pmf-conversions. Например:

class S
{
private:
  int debug_impl (int);
  int optimized_impl (int);

  typedef int Func (S*, int);

  static Func* resolver ();
public:

  int interface (int);
};

int S::debug_impl (int) { /* … */ }
int S::optimized_impl (int) { /* … */ }

S::Func* S::resolver ()
{
  int (S::*pimpl) (int)
    = getenv ("DEBUG") ? &S::debug_impl : &S::optimized_impl;

  // Cast triggers -Wno-pmf-conversions.
  return reinterpret_cast<Func*>(pimpl);
}

int S::interface (int) __attribute__ ((ifunc ("_ZN1S8resolverEv")));

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

interrupt
interrupt_handler

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

leaf

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

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

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

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

malloc

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

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

no_icf

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

no_instrument_function

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

no_profile_instrument_function

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

no_reorder

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

no_sanitize ("sanitize_option")

Атрибут no_sanitize для функций используется для того, чтобы сообщить компилятору, что он не должен проводить санитизацию каких-либо опций, упомянутых в sanitize_option. Список значений, приемлемых для опции -fsanitize, может быть предоставлен.

void __attribute__ ((no_sanitize ("alignment", "object-size")))
f () { /* Do something. */; }
void __attribute__ ((no_sanitize ("alignment,object-size")))
g () { /* Do something. */; }
no_sanitize_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 ("");

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

noipa

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

nonnull
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 включена, будет выведено предупреждение. См. Параметры для запроса или подавления предупреждений. Если опция -fno-delete-null-pointer-checks не отключена, компилятор может также выполнять оптимизации, основываясь на знании, что определённые аргументы функции не могут быть нулевыми. Кроме того, опция -fisolate-erroneous-paths-attribute может быть указана, чтобы GCC преобразовывал вызовы с нулевыми аргументами в функции, принимающие ненулевые, в ловушки. См. Параметры, управляющие оптимизацией.

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

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

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

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

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

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

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

noreturn

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

void fatal () __attribute__ ((noreturn));

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

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

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

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

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

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

nothrow

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

optimize (level, …)
optimize (string, …)

Атрибут optimize используется для указания того, что функция должна быть скомпилирована с другими параметрами оптимизации, чем указано в командной строке. Действительными аргументами являются константы неотрицательные целые числа и строки. Каждое числовое значение задаёт уровень оптимизации level. Каждый аргумент string состоит из одной или более подстрок, разделённых запятыми. Каждая подстрока, начинающаяся с буквы O, ссылается на параметр оптимизации, такой как -O0 или -Os. Другие подстроки используются как суффиксы префикса -f, совместно образуя имя параметра оптимизации. См. Параметры, управляющие оптимизацией.

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

Предоставление нескольких строк в качестве аргументов, разделённых запятыми, для указания нескольких опций, эквивалентно разделению суффиксов параметров запятой (‘,’) внутри одной строки. Пробелы внутри строк не допускаются.

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

patchable_function_entry

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

Функциональный атрибут patchable_function_entry может использоваться для изменения количества NOP любым желаемым значением. Синтаксис с двумя значениями такой же, как и для переключателя командной строки -fpatchable-function-entry=N,M, генерирующего N NOP, с точкой входа функции перед M-ым инструкцией NOP. M по умолчанию равен 0, если не указано, например, точка входа функции находится перед первой инструкцией NOP.

Если патч-входы функций включены глобально с помощью параметра командной строки -fpatchable-function-entry=N,M, тогда вы должны отключить инструментирование во всех функциях, которые являются частью фреймворка инструментирования, с помощью атрибута patchable_function_entry (0), чтобы предотвратить рекурсию.

pure

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

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

Например,

int hash (char *) __attribute__ ((pure));

сообщает GCC, что последующие вызовы функции hash со строкой будут заменены результатом первого вызова, при условии, что состояние программы, наблюдаемое функцией hash, включая содержимое массива, не изменяется между вызовами. Несмотря на то, что hash принимает аргумент указателя без const, он не должен изменять массив, на который указывает, или любой другой объект, значение которого может зависеть от остальной программы. Однако вызывающая сторона может безопасно изменять содержимое массива между последовательными вызовами функции (таким образом, оптимизация отключается). Ограничение также распространяется на объекты-члены, на которые ссылается указатель this в нестатических членах-функциях в C++.

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

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

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
sentinel (position)

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

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

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

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

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

simd
simd("mask")

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

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

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

stack_protect

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

target (string, …)

Несколько бэкэндов для обработки разных платформ реализуют атрибут target для указания того, что функция должна компилироваться с различными параметрами целевой платформы, отличными от указанных в командной строке. В качестве аргументов можно указать одну или несколько строк. Каждая строка состоит из одной или нескольких запятой, разделяемых суффиксов к префиксу -m вместе, образуя имя машинозависимого параметра. См. Параметры, Зависящие от Машины.

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

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

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

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

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

symver ("name2@nodename")

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

__attribute__ ((__symver__ ("foo@VERS_1"))) int
foo_v1 (void)
{
}

Создаст директиву .symver foo_v1, foo@VERS_1 в выходных данных ассемблера.

Определение нескольких версий одного и того же символа является ошибкой. В таком случае можно использовать псевдоним.

__attribute__ ((__symver__ ("foo@VERS_2")))
__attribute__ ((alias ("foo_v1")))
int symver_foo_v1 (void);

В этом примере создается псевдоним foo_v1 с именем символа symver_foo_v1, который будет версией VERS_2 символа foo.

Наконец, если параметр равен "name2@@nodename", то помимо создания версии символа (как если бы использовался "name2@nodename") версия также будет использована для разрешения name2 компоновщиком.

target_clones (options)

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

Например, на x86 вы могли бы скомпилировать функцию с target_clones("sse4.1,avx"). GCC создает два клона функции, один скомпилированный с -msse4.1, а другой с -mavx.

На PowerPC вы можете скомпилировать функцию с target_clones("cpu=power9,default"). GCC создаст два клона функции, один скомпилированный с -mcpu=power9, а другой с параметрами по умолчанию. GCC должен быть сконфигурирован для использования GLIBC 2.23 или более поздней версии, чтобы использовать атрибут target_clones.

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

Обратите внимание, что любой последующий вызов функции без target_clone из вызывающего модуля target_clone не приведет к копированию (клонированию для целевой платформы) вызываемой функции. Если вы хотите обеспечить такое поведение, рекомендуется объявить вызывающую функцию с атрибутом flatten.

unused

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

used

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

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

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

Объявление пространства имен 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, называя целевое определение псевдонима. target должен иметь тот же тип, что и объявление. Кроме того, если он обозначает переменную, он также должен иметь тот же размер и выравнивание, что и объявление. В любом из этих форм объявления weakref неявно помечает объявленный символ как weak. Без target, указанного как аргумент к weakref или alias, weakref эквивалентно weak (в этом случае объявление может быть extern).

/* Given the declaration: */
extern int y (void);

/* the following... */
static int x (void) __attribute__ ((weakref ("y")));

/* is equivalent to... */
static int x (void) __attribute__ ((weakref, alias ("y")));

/* or, alternatively, to... */
static int x (void) __attribute__ ((weakref));
static int x (void) __attribute__ ((alias ("y")));

Слабая ссылка — это псевдоним, который сам по себе не требует указания определения для целевого символа. Если целевой символ ссылается только через слабые ссылки, то он становится неопределённым символом weak. Однако, если он напрямую ссылается, то такие сильные ссылки преобладают, и для символа требуется определение, не обязательно в том же модуле трансляции.

Эффект эквивалентен перемещению всех ссылок на псевдоним в отдельный модуль трансляции, переименованию псевдонима в алиасируемый символ, объявлению его как слабого, компиляции двух отдельных модулей трансляции и выполнению компоновки со ссылочными выходными данными (т. е. ld -r) на них.

Объявление, к которому прикреплён weakref, и которое связано с именованным target, должно быть static.

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

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

Spec-Zone.ru

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