6.34.1 Общие атрибуты переменных
Следующие атрибуты поддерживаются на большинстве целей.
-
alias ("target") -
Атрибут переменной
aliasзаставляет объявление генерироваться как псевдоним другого символа, известного как цель псевдонима. За исключением квалификаторов верхнего уровня, цель псевдонима должна иметь тот же тип, что и псевдоним. Например, следующееint var_target; extern int __attribute__ ((alias ("var_target"))) var_alias;определяет
var_aliasкак псевдоним для переменнойvar_target.Ошибка, если цель псевдонима не определена в том же модуле трансляции, что и псевдоним.
Обратите внимание, что в отсутствие атрибута GCC предполагает, что разные объявления с внешней связью обозначают разные объекты. Использование как псевдонима, так и цели псевдонима для доступа к одному объекту не определено в модуле трансляции без объявления псевдонима с атрибутом.
Этот атрибут требует поддержки ассемблером и объектным файлом, и может быть недоступен на всех целях.
-
aligned aligned (alignment)-
Атрибут
alignedзадаёт минимальное выравнивание для переменной или поля структуры, измеряемое в байтах. При указании, выравнивание должно быть целой константой, степенью двойки. Указание без аргумента выравнивание подразумевает максимальное выравнивание для цели, которое часто, но не всегда, составляет 8 или 16 байт.Например, объявление:
int x __attribute__ ((aligned (16))) = 0;
заставляет компилятор выделять глобальную переменную
xна границе 16 байт. На 68040 это можно использовать совместно с выражениемasm, чтобы получить доступ к инструкцииmove16, которая требует 16-байтового выравнивания операндов.Вы также можете указать выравнивание полей структуры. Например, чтобы создать пару
intс выравниванием по слову двойной длины, можно написать:struct foo { int x[2] __attribute__ ((aligned (8))); };Это альтернатива созданию объединения с членом
double, что заставляет объединение иметь выравнивание по слову двойной длины.Как и в предыдущих примерах, вы можете явно указать выравнивание (в байтах), которое вы хотите использовать компилятору для данной переменной или поля структуры. В качестве альтернативы, вы можете опустить фактор выравнивания и попросить компилятор выровнять переменную или поле по умолчанию для целевой архитектуры, для которой вы компилируете. Умолчательное выравнивание достаточно для всех скалярных типов, но может быть недостаточно для всех векторных типов на цели, поддерживающей векторные операции. Умолчательное выравнивание фиксировано для конкретной целевой ABI.
GCC также предоставляет специфичный для цели макрос
__BIGGEST_ALIGNMENT__, который является наибольшим выравниванием, когда-либо использовавшимся для любого типа данных на целевой машине, для которой вы компилируете. Например, вы можете написать:short array[3] __attribute__ ((aligned (__BIGGEST_ALIGNMENT__)));
Компилятор автоматически устанавливает выравнивание для объявленной переменной или поля на
__BIGGEST_ALIGNMENT__. Это часто может повысить эффективность операций копирования, так как компилятор может использовать любые инструкции для копирования больших кусков памяти при выполнении копирования к или из переменных или полей, которые вы выровняли таким образом. Обратите внимание, что значение__BIGGEST_ALIGNMENT__может меняться в зависимости от параметров командной строки.При использовании на структуре или члене структуры атрибут
alignedможет только увеличивать выравнивание; для его уменьшения также должен быть указан атрибутpacked. При использовании в качестве части typedef атрибутalignedможет как увеличивать, так и уменьшать выравнивание, а указание атрибутаpackedгенерирует предупреждение.Обратите внимание, что эффективность атрибутов
alignedдля статических переменных может быть ограничена внутренними ограничениями системного линкера и/или формата объектных файлов. На некоторых системах линкер может только организовать выравнивание переменных до определённого максимального выравнивания. (Для некоторых линковщиков максимальное поддерживаемое выравнивание может быть очень маленьким.) Если ваш линкер способен выравнивать переменные только до максимального выравнивания 8 байт, то указаниеaligned(16)в__attribute__всё равно даёт вам выравнивание только 8 байт. Обратитесь к документации вашего линкера за дополнительной информацией.Переменные стека не подвержены ограничениям линковщика; GCC может правильно выровнять их на любой цели.
Атрибут
alignedтакже может использоваться для функций (см. Общие атрибуты функций). -
warn_if_not_aligned (alignment) -
Этот атрибут задаёт порог для поля структуры, измеряемый в байтах. Если поле структуры выровнено ниже порога, будет выдано предупреждение. Например, объявление:
struct foo { int i1; int i2; unsigned long long x __attribute__ ((warn_if_not_aligned (16))); };заставляет компилятор выдать предупреждение о
struct foo, например, «предупреждение: выравнивание 8 для 'struct foo' меньше 16». Компилятор также выдаёт предупреждение, например, «предупреждение: смещение 'x' 8 в 'struct foo' не выровнено по 16», когда поле структуры имеет смещение, не выровненное по указанному значению:struct __attribute__ ((aligned (16))) foo { int i1; int i2; unsigned long long x __attribute__ ((warn_if_not_aligned (16))); };Это предупреждение можно отключить с помощью -Wno-if-not-aligned. Атрибут
warn_if_not_alignedтакже может использоваться для типов (см. Общие атрибуты типов). -
strict_flex_array (level) -
Атрибут
strict_flex_arrayследует прикреплять к последнему полю массива структуры. Он управляет тем, когда следует рассматривать конечное поле массива структуры как гибкий член массива для доступа к элементам такого массива. уровень должен быть целым числом от 0 до 3.уровень=0 — это наименее строгий уровень, все конечные массивы структур рассматриваются как гибкие члены массивов. уровень=3 — самый строгий уровень, только когда конечный массив объявлен как гибкий член массива в соответствии со стандартом C99 и далее («[]»), он рассматривается как гибкий член массива.
Есть ещё два уровня между 0 и 3, которые предоставляются для поддержки более старых кодов, использующих расширение GCC нулевой длины массива («[0]») или одноэлементный массив как гибкие члены массива («[1]»): Когда уровень равен 1, конечный массив рассматривается как гибкий член массива, когда он объявлен как «[]», «[0]» или «[1]»; когда уровень равен 2, конечный массив рассматривается как гибкий член массива, когда он объявлен как «[]» или «[0]».
Этот атрибут может использоваться с -fstrict-flex-arrays или без него. Когда оба атрибут и опция присутствуют одновременно, уровень строгости для конкретного конечного поля массива определяется атрибутом.
-
alloc_size (position) alloc_size (position-1, position-2)-
Атрибут
alloc_sizeможет быть применён к объявлению указателя на функцию, которая возвращает указатель и принимает по крайней мере один аргумент целого типа. Он указывает, что возвращаемый указатель указывает на объект, размер которого задаётся аргументом функции в позиции position, или произведением аргументов в позициях position-1 и position-2. Значимые размеры — это положительные значения меньшеPTRDIFF_MAX. Другие размеры диагностируются при обнаружении. GCC использует эту информацию для улучшения результатов__builtin_object_size.Например, следующие объявления
typedef __attribute__ ((alloc_size (1, 2))) void* (*calloc_ptr) (size_t, size_t); typedef __attribute__ ((alloc_size (1))) void* (*malloc_ptr) (size_t);
указывают, что
calloc_ptr— это указатель на функцию, которая, подобно стандартной C-функцииcalloc, возвращает объект, размер которого задаётся произведением аргументов 1 и 2, и аналогично, чтоmalloc_ptr, подобно стандартной C-функцииmalloc, возвращает объект, размер которого задаётся аргументом 1 функции. -
cleanup (cleanup_function) -
Атрибут
cleanupвыполняет функцию, когда переменная выходит из области видимости. Этот атрибут может быть применён только к переменным автоматической области видимости функции; он не может быть применён к параметрам или переменным со статической продолжительностью хранения. Функция должна принимать один параметр — указатель на тип, совместимый с переменной. Значение возврата функции (если оно есть) игнорируется.Если -fexceptions включён, то cleanup_function выполняется во время разворачивания стека, происходящего во время обработки исключения. Обратите внимание, что атрибут
cleanupне позволяет перехватить исключение, а только выполнить действие. Не определено, что произойдёт, если cleanup_function не вернётся нормально. -
common nocommon-
Атрибут
commonзапрашивает у GCC разместить переменную в общем хранилище. Атрибутnocommonзапрашивает обратное — выделить для неё место напрямую.Эти атрибуты переопределяют настройки по умолчанию, выбранные флагами -fno-common и -fcommon соответственно.
-
copy copy (variable)-
Атрибут
copyприменяет набор атрибутов, с помощью которых была объявлена переменная variable, к объявлению переменной, к которой применяется атрибут. Атрибут предназначен для библиотек, которые определяют псевдонимы, которые должны указывать тот же набор атрибутов, что и алиасируемые символы. Атрибутcopyможет использоваться с переменными, функциями или типами. Однако тип символа, к которому применяется атрибут (либо переменная, либо функция), должен соответствовать типу символа, на который ссылается аргумент. Атрибутcopyкопирует только синтаксические и семантические атрибуты, но не атрибуты, влияющие на связь или видимость символа, такие какalias,visibility, илиweak. Атрибутdeprecatedтакже не копируется. См. Общие атрибуты функций. См. Общие атрибуты типов. -
deprecated deprecated (msg)
-
Атрибут
deprecatedприводит к появлению предупреждения, если переменная используется где-либо в исходном файле. Это полезно для идентификации переменных, которые ожидается удалить в будущей версии программы. Предупреждение также включает местоположение объявления устаревшей переменной, что позволяет пользователям легко найти дополнительную информацию о том, почему переменная устарела или что им следует сделать вместо этого. Обратите внимание, что предупреждение возникает только для использования:extern int old_var __attribute__ ((deprecated)); extern int old_var; int new_fn () { return old_var; }приводит к появлению предупреждения на строке 3, но не на строке 2. Необязательный аргумент msg, который должен быть строкой, выводится в предупреждении, если он присутствует.
Атрибут
deprecatedтакже может использоваться для функций и типов (см. Общие атрибуты функций, см. Общие атрибуты типов).Сообщение, прикрепленное к атрибуту, зависит от настройки опции -fmessage-length.
-
unavailable unavailable (msg)-
Атрибут
unavailableуказывает, что переменная, помеченная таким образом, недоступна, если она используется где-либо в исходном файле. Он ведет себя так же, как атрибутdeprecated, за исключением того, что компилятор выведет ошибку, а не предупреждение.Ожидается, что элементы, помеченные как
deprecated, в конечном итоге будут удалены из интерфейсов и станут недоступными. Этот атрибут позволяет соответствующим образом их помечать.Атрибут
unavailableтакже может использоваться для функций и типов (см. Общие атрибуты функций, см. Общие атрибуты типов). -
mode (mode) -
Этот атрибут задаёт тип данных для объявления — тип, соответствующий режиму mode. Это позволяет запросить целочисленный или с плавающей запятой тип в соответствии с его шириной.
См. Режимы машины в документации по внутреннему устройству GNU компилятора GCC для списка возможных ключевых слов для mode. Вы также можете указать режим
byteили__byte__для обозначения режима, соответствующего целочисленному типу одного байта,wordили__word__для режима целочисленного типа одного слова иpointerили__pointer__для режима, используемого для представления указателей. -
nonstring -
Атрибут
nonstringпеременной указывает, что объявление объекта или члена типа массив изchar,signed char, илиunsigned char, или указатель на такой тип предназначен для хранения символьных массивов, которые не обязательно содержат завершающийNUL. Это полезно для обнаружения использования таких массивов или указателей с функциями, которые ожидаютNUL-завершённые строки и для предотвращения предупреждений при использовании такого массива или указателя в качестве аргумента функции обработки ограниченной строки, такой какstrncpy. Например, без атрибута GCC выдаст предупреждение для вызоваstrncpyниже, потому что он может обрезать копирование без добавления завершающего символаNUL. Использование атрибута позволяет подавить предупреждение. Однако, когда массив объявлен с атрибутом, вызовstrlenдиагностируется, поскольку, когда массив не содержитNUL-завершённой строки, вызов не определён. Для копирования, сравнения или поиска массивов символов без строки используйте функцииmemcpy,memcmp,memchr, и другие функции, которые работают с массивами байтов. Кроме того, вызовstrnlenиstrndupс такими массивами безопасен при условии указания подходящей границы и не диагностируется.struct Data { char name [32] __attribute__ ((nonstring)); }; int f (struct Data *pd, const char *s) { strncpy (pd->name, s, sizeof pd->name); … return strlen (pd->name); // unsafe, gets a warning } -
packed -
Атрибут
packedуказывает, что член структуры должен иметь наименьшее возможное выравнивание — один бит для битового поля и один байт в противном случае, если большее значение не задано с помощью атрибутаaligned. Атрибут не применяется к объектам, не являющимся членами.Например, в структуре ниже, член-массив
xупакован таким образом, что он сразу следует заaбез промежуточного заполнения:struct foo { char a; int x[2] __attribute__ ((packed)); };Примечание: Серии GCC 4.1, 4.2 и 4.3 игнорируют атрибут
packedдля битовых полей типаchar. Это было исправлено в GCC 4.4, но это изменение может привести к различиям в расположении структуры. Обратитесь к документации -Wpacked-bitfield-compat для получения дополнительной информации. -
section ("section-name") -
Обычно компилятор помещает сгенерированные объекты в секции, такие как
dataиbss. Однако иногда вам нужны дополнительные секции или вам нужны определённые переменные, чтобы они отображались в специальных секциях, например, для отображения на специальном оборудовании. Атрибутsectionуказывает, что переменная (или функция) находится в определённой секции. Например, эта небольшая программа использует несколько специфичных имён секций:struct duart a __attribute__ ((section ("DUART_A"))) = { 0 }; struct duart b __attribute__ ((section ("DUART_B"))) = { 0 }; char stack[10000] __attribute__ ((section ("STACK"))) = { 0 }; int init_data __attribute__ ((section ("INITDATA"))); main() { /* Initialize stack pointer */ init_sp (stack + sizeof (stack)); /* Initialize initialized data */ memcpy (&init_data, &data, &edata - &data); /* Turn on the serial ports */ init_duart (&a); init_duart (&b); }Используйте атрибут
sectionс глобальными переменными, а не локальными, как показано в примере.Вы можете использовать атрибут
sectionс инициализированными или неинициализированными глобальными переменными, но компоновщик требует, чтобы каждый объект был определён один раз, за исключением того, что неинициализированные переменные предварительно помещаются в секциюcommon(илиbss) и могут быть многократно «определены». Использование атрибутаsectionизменяет секцию, в которую попадает переменная, и может привести к выдаче ошибки компоновщиком, если у неинициализированной переменной есть несколько определений. Вы можете принудительно инициализировать переменную с помощью флага -fno-common или атрибутаnocommon.Некоторые форматы файлов не поддерживают произвольные секции, поэтому атрибут
sectionнедоступен на всех платформах. Если вам нужно отобразить всё содержимое модуля в определённой секции, воспользуйтесь возможностями компоновщика. -
tls_model ("tls_model") -
Атрибут
tls_modelустанавливает модель хранения потоков (см. Хранение данных для потоков) для определённой переменной__thread, переопределяя командную строку -ftls-model= на основе переменной. Аргумент tls_model должен быть одним изglobal-dynamic,local-dynamic,initial-execилиlocal-exec.Не все целевые платформы поддерживают этот атрибут.
-
unused -
Этот атрибут, прикреплённый к переменной или полю структуры, означает, что переменная или поле могут быть неиспользуемыми. GCC не выводит предупреждение для этой переменной или поля.
-
used -
Этот атрибут, прикреплённый к переменной со статическим хранением, означает, что переменная должна быть выведена, даже если кажется, что на неё нет ссылок.
При применении к статическому члену данных шаблона класса C++, атрибут также означает, что член инициализируется, если класс сам инициализируется.
-
retain -
Для целевых платформ ELF, поддерживающих GNU или FreeBSD OSABI, этот атрибут защитит переменную от сборки мусора компоновщиком. Для поддержки этого поведения переменные, которые не были помещены в конкретные секции (например, атрибутом
section, или опцией-fdata-sections), будут помещены в новые уникальные секции.Эта дополнительная функциональность требует Binutils версии 2.36 или более поздней.
-
uninitialized -
Этот атрибут, прикреплённый к переменной со автоматическим хранением, означает, что переменная не должна быть инициализирована компилятором автоматически при наличии опции
-ftrivial-auto-var-init.С опцией
-ftrivial-auto-var-init, все автоматические переменные, не имеющие явных инициализаторов, будут инициализированы компилятором. Эти дополнительные инициализации компилятора могут привести к издержкам во время выполнения, иногда значительно.Этот атрибут можно использовать для обозначения некоторых переменных, которые нужно исключить из такой автоматической инициализации, чтобы уменьшить накладные расходы во время выполнения.
Этот атрибут не имеет эффекта, когда опция
-ftrivial-auto-var-initотсутствует. -
vector_size (bytes) -
Этот атрибут указывает размер вектора для типа объявленной переменной, измеряемый в байтах. Тип, к которому он применяется, известен как базовый тип. Аргумент bytes должен быть положительной степенью двойки, кратной размеру базового типа. Например, объявление:
int foo __attribute__ ((vector_size (16)));
приводит к тому, что компилятор устанавливает размер для
foo, в 16 байтов, разделённых на блоки размеромint. Предполагая 32-битныйint, типfooявляется вектором из четырёх блоков по четыре байта каждый, и соответствующий размерfooравенV4SI. См. Использование векторных инструкций через встроенные функции для подробностей работы с векторными переменными.Этот атрибут применим только к целочисленным и с плавающей точкой скалярам, хотя массивы, указатели и значения возвращаемых функций разрешены в сочетании с этим конструктом.
Агрегаты с этим атрибутом недействительны, даже если они имеют тот же размер, что и соответствующий скаляр. Например, объявление:
struct S { int a; }; struct S __attribute__ ((vector_size (16))) foo;недействительно, даже если размер структуры такой же, как размер
int. -
visibility ("visibility_type") -
Этот атрибут влияет на связь объявления, к которому он прикреплён. Атрибут
visibilityописан в Общих атрибутах функций. -
weak -
Атрибут
weakописан в Общих атрибутах функций. -
noinit
-
Любые данные с атрибутом
noinitне будут инициализированы кодом запуска C-runtime или загрузчиком программы. Отсутствие инициализации данных таким образом может сократить время запуска программы.Этот атрибут специфичен для целевых платформ ELF и опирается на скрипт линковщика для размещения секций с префиксом
.noinitв нужном месте. -
persistent -
Любые данные с атрибутом
persistentне будут инициализированы кодом запуска C-runtime, но будут инициализированы загрузчиком программы. Это позволяет значению переменной сохраняться («persist») между перезагрузками процессора.Этот атрибут специфичен для целевых платформ ELF и опирается на скрипт линковщика для размещения секций с префиксом
.persistentв нужном месте. В частности, требуется какой-либо тип энергонезависимой, перезаписываемой памяти. -
objc_nullability (nullability kind) (Objective-C and Objective-C++ only) -
Этот атрибут применяется только к указателям переменных. Он позволяет маркировать указатель одним из четырёх возможных значений, описывающих условия, при которых указатель может иметь значение
nil. В большинстве случаев атрибут предназначен для внутреннего представления нуллируемости свойств и методов (заданных ключевыми словами языка); использование его напрямую не рекомендуется.Когда вид нуллируемости равен
"unspecified"или0, ничего не известно об условиях, при которых указатель может бытьnil. Уточнение этого состояния служит для предотвращения ложных срабатываний в диагностике.Когда вид нуллируемости равен
"nonnull"или1, указатель не имеет смысла, если онnil, и поэтому компилятор свободен генерировать диагностику, если можно определить, что значение будетnil.Когда вид нуллируемости равен
"nullable"или2, указатель может бытьnilи иметь соответствующий смысл.Когда вид нуллируемости равен
"resettable"или3(используется только в контексте списков атрибутов свойств), это описывает случай, когда установщик свойства может принять значениеnil(что, возможно, приводит к сбросу свойства каким-либо способом к значению по умолчанию), но при этом для свойства getter никогда не будет верно возвращатьnil.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gcc/Common-Variable-Attributes.html