6.33.1 Общие атрибуты функций ¶
Следующие атрибуты поддерживаются на большинстве целевых платформ.
accessaccess (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’ не определено в том же модуле трансляции.
Данный атрибут требует поддержки в ассемблере и объектных файлах, и может быть недоступен на всех целевых платформах.
alignedaligned (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++, ссылки в качестве аргументов. Аналогично, функция, вызывающая неконстантную функцию, обычно не должна быть константной сама по себе. constructordestructorconstructor (priority)destructor (priority)-
Атрибут
constructorвызывает автоматическое вызов функции перед входом вmain (). Аналогично, атрибутdestructorвызывает автоматическое вызов функции после завершенияmain ()или вызоваexit (). Функции с такими атрибутами полезны для инициализации данных, которые неявно используются во время выполнения программы.На некоторых целевых платформах эти атрибуты также принимают целочисленный аргумент для задания приоритета, управляющего порядком выполнения функций-конструкторов и деструкторов. Конструктор с меньшим приоритетом выполняется перед конструктором с большим приоритетом; обратное соотношение действует для деструкторов. Таким образом, если у вас есть конструктор, выделяющий ресурс, и деструктор, освобождающий тот же ресурс, обе функции обычно имеют одинаковый приоритет. Приоритеты для функций-конструкторов и деструкторов совпадают с теми, которые указаны для объектов C++ в области именования (см. C++-специфичные атрибуты переменных, функций и типов). Однако в настоящее время порядок вызова конструкторов для объектов C++ со статической продолжительностью хранения и функций, снабжённых атрибутом
constructor, не определён. В смешанных объявлениях атрибутinit_priorityможно использовать для наложения определённого порядка.Использование аргументных форм атрибутов
constructorиdestructorна целевых платформах, где функция не поддерживается, приводит к ошибке. copycopy (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); deprecateddeprecated (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/Openstrfmon, а также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, каждый с различным значением аргумента, соответствующие фактические аргументы функции проверяются по отношению ко всем строкам формата, обозначенным атрибутами. Эта возможность предназначена для поддержки функций GNUngettext.Параметр 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 или выше.
interruptinterrupt_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_addressno_address_safety_analysis-
Атрибут
no_sanitize_addressдля функций используется для того, чтобы сообщить компилятору, что он не должен инструментировать обращения к памяти в функции при компиляции с опцией -fsanitize=address. Атрибутno_address_safety_analysisявляется устаревшим псевдонимом атрибутаno_sanitize_address, новый код должен использоватьno_sanitize_address. no_sanitize_thread-
Атрибут
no_sanitize_threadдля функций используется для того, чтобы сообщить компилятору, что он не должен инструментировать обращения к памяти в функции при компиляции с опцией -fsanitize=thread. no_sanitize_undefined-
Атрибут
no_sanitize_undefinedдля функций используется для того, чтобы сообщить компилятору, что он не должен проверять неопределённое поведение в функции при компиляции с опцией -fsanitize=undefined. no_split_stack-
Если задана опция -fsplit-stack, функции имеют небольшой пролог, который определяет, следует ли разделять стек. Функции с атрибутом
no_split_stackне имеют этого пролога и, следовательно, могут выполняться с небольшим количеством доступного пространства стека. no_stack_limit-
Этот атрибут локально переопределяет опции командной строки -fstack-limit-register и -fstack-limit-symbol; он имеет эффект отключения проверки лимита стека в функции, к которой он применяется.
noclone-
Этот атрибут функции предотвращает рассмотрение функции для клонирования — механизма, который создаёт специализированные копии функций и который (в настоящее время) выполняется путём интерпроцедурной константной прогонки.
noinline-
Этот атрибут функции предотвращает рассмотрение функции для встраивания. Если у функции нет побочных эффектов, существуют оптимизации, помимо встраивания, которые приводят к тому, что вызовы функций оптимизируются, хотя вызов функции и активен. Чтобы предотвратить оптимизацию таких вызовов, поместите
asm ("");(см. Расширенный ассемблер - ассемблерные инструкции с операндами выражений C) в вызываемую функцию, чтобы служить специальным побочным эффектом.
noipa-
Отключить интерпроцедурные оптимизации между функцией с этим атрибутом и её вызывающими функциями, как если бы тело функции было недоступно при оптимизации вызывающих функций, а вызывающие функции были недоступны при оптимизации тела. Этот атрибут подразумевает атрибуты
noinline,nocloneиno_icf. Однако этот атрибут не эквивалентен комбинации других атрибутов, так как его цель заключается в подавлении существующих и будущих оптимизаций, использующих межпроцедурный анализ, включая те, которые не имеют атрибута, подходящего для их отключения по отдельности. Этот атрибут в основном поддерживается для целей тестирования компилятора. nonnullnonnull (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не доступен на всех платформах. Если вам нужно отобразить всё содержимое модуля в конкретной секции, рассмотрите использование средств компоновщика вместо этого. sentinelsentinel (position)
-
Этот атрибут функции указывает, что аргумент в вызове функции должен быть явным
NULL. Атрибут действителен только для вариадических функций. По умолчанию ожидается, что семафор будет последним аргументом вызова функции. Если необязательный аргумент position указан в атрибуте, семафор должен находиться на позиции position, считая от конца списка аргументов.__attribute__ ((sentinel)) is equivalent to __attribute__ ((sentinel(0)))
Атрибут автоматически устанавливается с позицией 0 для встроенных функций
execlиexeclp. Для встроенной функцииexecleатрибут устанавливается с позицией 1.Допустимый
NULLв этом контексте определяется как ноль с любым типом указателя на объект. Если ваша система определяет макросNULLс целочисленным типом, вам необходимо добавить явное приведение типов. Во время установки GCC заменяет системный заголовок<stddef.h>на копию, которая переопределяет NULL должным образом.Предупреждения о пропущенных или неправильных семафорах включены с помощью -Wformat.
simdsimd("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 ассемблера и компоновщика. weakrefweakref ("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.
© 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