6.4.2.1 Общие атрибуты переменных
Следующие атрибуты поддерживаются на большинстве целевых платформ.
-
alias ("target") -
Атрибут переменной
aliasприводит к тому, что объявление выводится как псевдоним другого символа, называемого целевым символом псевдонима. За исключением квалификаторов верхнего уровня, целевой символ псевдонима должен иметь тот же тип, что и псевдоним. Например, следующий фрагментint var_target; extern int __attribute__ ((alias ("var_target"))) var_alias;определяет
var_aliasкак псевдоним переменнойvar_target.Если целевой символ псевдонима не определён в той же единице трансляции, что и псевдоним, возникает ошибка.
Обратите внимание: если атрибут не указан, GCC предполагает, что разные объявления с внешним связыванием обозначают разные объекты. Использование псевдонима и целевого символа псевдонима для доступа к одному и тому же объекту не определено, если в единице трансляции нет объявления псевдонима с этим атрибутом.
Для этого атрибута требуются поддержка ассемблера и поддержка формата объектных файлов; он может быть недоступен на некоторых целевых платформах.
-
aligned aligned (alignment)-
Атрибут
alignedзадаёт минимальное выравнивание переменной или поля структуры в байтах. Если он указан, значение alignment должно быть целой константой, являющейся степенью 2. Если аргумент alignment не задан, подразумевается максимальное выравнивание для целевой платформы, которое часто, но далеко не всегда, составляет 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также можно использовать для функций (см. раздел Общие атрибуты функций.) -
counted_by (count) -
Атрибут
counted_byможно присоединить к гибкому члену массива C99 в структуре. Он указывает, что количество элементов массива задаётся полем «count» той же структуры, в которой находится гибкий член массива.Пока этот атрибут доступен только в C. В C++ он игнорируется.
GCC может использовать эти сведения для более точного определения размера объектов таких структур и выдавать более точные результаты при диагностике во время компиляции, а также при использовании возможностей времени выполнения, таких как санитайзер границ массива и встроенная функция
__builtin_dynamic_object_size.Например, следующий код:
struct P { size_t count; char other; char array[] __attribute__ ((counted_by (count))); } *p;указывает, что
array— это гибкий член массива, количество элементов которого задаётся полемcountтой же структуры.Поле, задающее количество элементов, должно иметь целочисленный тип. В противном случае компилятор выдаёт ошибку и игнорирует атрибут.
Если полю, задающему количество элементов, присвоено отрицательное целое значение, компилятор считает это значение равным нулю.
Явная аннотация
counted_byзадаёт связь между двумя объектами,p->arrayиp->count, и для этой пары действуют следующие требования:-
p->countдолжен быть инициализирован до первого обращения кp->array; -
p->arrayвсегда содержит как минимумp->countдоступных элементов. Это условие должно выполняться и после обновления любых связанных объектов во время выполнения программы.
Программист несёт ответственность за постоянное соблюдение перечисленных требований. В противном случае компилятор выдаёт предупреждения, а результаты работы санитайзера границ массива и встроенной функции
__builtin_dynamic_object_sizeне определены.Важная особенность этого атрибута заключается в том, что при обращении к полю — гибкому члену массива используется последнее значение, присвоенное полю, задающему количество элементов, до этого обращения. Например:
p->count = val1; p->array[20] = 0; // ref1 to p->array p->count = val2; p->array[30] = 0; // ref2 to p->array
В приведённом выше примере в
ref1используетсяval1в качестве количества элементов вp->array, а вref2—val2в качестве количества элементов вp->array. -
-
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— это указатель на функцию, которая, подобно стандартной функции Ccalloc, возвращает объект, размер которого задаётся произведением аргументов 1 и 2; аналогично,malloc_ptr, подобно стандартной функции Cmalloc, возвращает объект, размер которого задаётся аргументом 1 функции. -
cleanup (cleanup_function) -
Атрибут
cleanupвызывает функцию при выходе переменной из области видимости. Его можно применять только к автоматическим переменным в области видимости функции; его нельзя применять к параметрам или переменным со статической длительностью хранения. Функция должна принимать один параметр — указатель на тип, совместимый с типом переменной. Возвращаемое функцией значение (если оно есть) игнорируется.Если у нескольких переменных в одной области видимости есть атрибуты
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.
-
mode (mode) -
Этот атрибут задаёт тип данных для объявления — тип, соответствующий режиму mode. Таким образом можно запросить целочисленный тип или тип с плавающей точкой заданной ширины.
Список возможных ключевых слов для mode см. в разделе Режимы машин руководства «Внутреннее устройство GNU Compiler Collection (GCC)». Также можно указать режим
byteили__byte__для однобайтового целого числа,wordили__word__для целого числа размером в одно машинное слово иpointerили__pointer__для режима, используемого для представления указателей. -
no_icf -
Этот атрибут переменной запрещает объединять её с другой эквивалентной переменной.
-
noinit -
Данные с атрибутом
noinitне инициализируются кодом запуска среды выполнения C или загрузчиком программы. Такая неинициализация данных может сократить время запуска программы.Этот атрибут предназначен только для целевых платформ ELF и зависит от сценария компоновщика, который должен размещать секции с префиксом
.noinitв нужном месте. -
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 } -
objc_nullability (nullability kind) (Objective-C and Objective-C++ only) -
Этот атрибут применяется только к переменным-указателям. Он позволяет пометить указатель одним из четырёх возможных значений, описывающих условия, при которых указатель может иметь значение
nil. В большинстве случаев этот атрибут предназначен для внутреннего представления допустимости значения null у свойств и методов (задаваемой ключевыми словами языка); использовать его напрямую не рекомендуется.Если nullability kind имеет значение
"unspecified"или0, условия, при которых указатель может бытьnil, неизвестны. Выделение этого состояния в отдельный вид позволяет избежать ложных срабатываний при диагностике.Если nullability kind имеет значение
"nonnull"или1, указатель не имеет смысла, если онnil, поэтому компилятор может выдавать диагностику, если удаётся определить, что значение будетnil.Если nullability kind имеет значение
"nullable"или2, указатель может бытьnilи при этом иметь смысл.Если nullability kind имеет значение
"resettable"или3(используется только в контексте списков атрибутов свойств), это описывает случай, когда сеттер свойства может принимать значениеnil(что, возможно, сбрасывает свойство некоторым образом в значение по умолчанию), но геттер свойства никогда не должен возвращатьnil. -
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. -
persistent -
Данные с атрибутом
persistentне инициализируются кодом запуска среды выполнения C, но инициализируются загрузчиком программы. Благодаря этому значение переменной может «сохраняться» между сбросами процессора.Этот атрибут предназначен только для целевых платформ ELF и зависит от сценария компоновщика, который должен размещать секции с префиксом
.persistentв нужном месте. В частности, требуется некоторый тип энергонезависимой памяти с возможностью записи. -
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доступен не на всех платформах. Если требуется поместить всё содержимое модуля в определённую секцию, рассмотрите возможность использования средств компоновщика. -
strict_flex_array (level) -
Атрибут
strict_flex_arrayследует прикреплять к последнему полю массива структуры. Он определяет, в каких случаях при доступе к элементам последнего поля массива структуры это поле следует считать гибким членом массива. Значение level должно быть целым числом от 0 до 3.Уровень level=0 является наименее строгим: все массивы в конце структур считаются гибкими членами массива. Уровень level=3 является наиболее строгим: гибким членом массива считается только последний массив, объявленный как гибкий член массива согласно стандарту C99 или более позднему стандарту («[]»).
Между уровнями 0 и 3 предусмотрены ещё два уровня для поддержки старого кода, в котором в качестве гибких членов массива используются расширение GCC для массивов нулевой длины («[0]») или массивы из одного элемента («[1]»). При значении level 1 последний массив считается гибким членом массива, если он объявлен как «[]», «[0]» или «[1]». При значении level 2 последний массив считается гибким членом массива, если он объявлен как «[]» или «[0]».
Этот атрибут можно использовать с параметром командной строки -fstrict-flex-arrays или без него. Если атрибут и параметр заданы одновременно, строгость обработки конкретного последнего поля массива определяется атрибутом.
Атрибут
strict_flex_arrayвзаимодействует с параметром -Wstrict-flex-arrays. Дополнительные сведения см. в разделе Параметры запроса или отключения предупреждений. -
tls_model ("tls_model") -
Атрибут
tls_modelзадаёт модель локального хранилища потока (см. раздел Локальное хранилище потока) для конкретной переменной__thread, переопределяя параметр командной строки -ftls-model= отдельно для этой переменной. Аргумент tls_model должен иметь значениеglobal-dynamic,local-dynamic,initial-execилиlocal-exec.Этот атрибут поддерживается не всеми целевыми платформами.
-
unavailable unavailable (msg)-
Атрибут
unavailableуказывает, что помеченная им переменная недоступна, если она используется где-либо в исходном файле. Он работает так же, как атрибутdeprecated, но компилятор выдаёт ошибку, а не предупреждение.Предполагается, что элементы, помеченные как
deprecated, со временем будут удалены из интерфейсов и станут недоступными. Этот атрибут позволяет пометить их соответствующим образом.Атрибут
unavailableтакже можно использовать для функций и типов (см. раздел Общие атрибуты функций, а также раздел Общие атрибуты типов). -
unused -
Этот атрибут, прикреплённый к переменной или полю структуры, означает, что они могут не использоваться. GCC не выдаёт предупреждение для этой переменной или поля.
-
used -
Этот атрибут, прикреплённый к переменной со статической длительностью хранения, означает, что переменную необходимо вывести, даже если она, по-видимому, нигде не используется.
Если атрибут применяется к статическому члену данных шаблона класса C++, он также означает, что этот член создаётся, если создаётся сам класс.
-
retain -
Для целевых платформ ELF, поддерживающих GNU OSABI или 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. Если размерintравен 32 битам, типfooпредставляет собой вектор из четырёх единиц размером по четыре байта, а соответствующий режимfoo—V4SI. Сведения об операциях с векторными переменными см. в разделе Использование векторных инструкций с помощью встроенных функций.Этот атрибут применим только к целочисленным скалярным типам и скалярным типам с плавающей точкой, хотя вместе с этой конструкцией допускается использовать массивы, указатели и возвращаемые функциями значения.
Агрегатные типы с этим атрибутом недопустимы, даже если их размер совпадает с размером соответствующего скалярного типа. Например, объявление:
struct S { int a; }; struct S __attribute__ ((vector_size (16))) foo;недопустимо, даже если размер структуры совпадает с размером
int. -
visibility ("visibility_type") -
Этот атрибут влияет на связывание объявления, к которому он прикреплён. Описание атрибута
visibilityсм. в разделе Общие атрибуты функций. -
warn_if_not_aligned (alignment) -
Этот атрибут задаёт порог для поля структуры в байтах. Если выравнивание поля меньше порогового значения, выдаётся предупреждение. Например, объявление:
struct foo { int i1; int i2; unsigned long long x __attribute__ ((warn_if_not_aligned (16))); };заставляет компилятор выдать предупреждение для
struct foo, например «warning: alignment 8 of 'struct foo' is less than 16». Компилятор также выдаёт предупреждение, например «warning: 'x' offset 8 in 'struct foo' isn't aligned to 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также можно использовать для типов (см. раздел Общие атрибуты типов.) -
weak -
Описание атрибута
weakсм. в разделе Общие атрибуты функций.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-15.3.0/gcc/Common-Variable-Attributes.html