6.34.1 Общие атрибуты переменных
Следующие атрибуты поддерживаются на большинстве целевых платформ.
alias ("target")Атрибут переменной
aliasзаставляет объявление генерироваться в виде псевдонима для другого символа, известного как целевой псевдоним. За исключением квалификаторов верхнего уровня, целевой псевдоним должен иметь тот же тип, что и псевдоним. Например, следующееint var_target; extern int __attribute__ ((alias ("var_target"))) var_alias;определяет
var_aliasкак псевдоним для переменнойvar_target.Ошибка возникает, если целевой псевдоним не определён в том же модуле трансляции, что и псевдоним.
Обратите внимание, что в отсутствие этого атрибута GCC предполагает, что различные объявления с внешней связью обозначают различные объекты. Использование как псевдонима, так и целевого псевдонима для доступа к одному объекту в модуле трансляции без объявления псевдонима с этим атрибутом является неопределённым поведением.
Данный атрибут требует поддержки ассемблера и объектных файлов и может быть недоступен на всех целевых платформах.
alignedaligned (alignment)Атрибут
alignedзадаёт минимальное выравнивание для переменной или поля структуры, измеряемое в байтах. При указании, alignment должен быть целой константой, являющейся степенью двойки. Отсутствие аргумента 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также можно использовать для функций (см. Общие атрибуты функций).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’. Компилятор также выдаёт предупреждение, например, ‘предупреждение: смещение 8 для 'x' в '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также можно использовать для типов (см. Общие атрибуты типов). alloc_size (position)alloc_size (position-1, position-2)-
Атрибут переменной
alloc_sizeможет быть применён к объявлению указателя на функцию, возвращающую указатель и принимающую по крайней мере один аргумент целочисленного типа. Он указывает, что возвращаемый указатель ссылается на объект, размер которого задаётся аргументом функции в позиции position-1 или произведением аргументов в позициях 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 не вернётся нормально. commonnocommon-
Атрибут
commonпросит GCC поместить переменную в хранилище «common». Атрибутnocommonпросит наоборот — выделить место для неё напрямую.Эти атрибуты переопределяют значения, выбранные по умолчанию флагами -fno-common и -fcommon соответственно.
copycopy (variable)-
Атрибут
copyприменяет набор атрибутов, с помощью которых была объявлена переменная, к объявлению переменной, к которой применяется атрибут. Атрибут предназначен для библиотек, которые определяют псевдонимы, которые, как ожидается, будут указывать тот же набор атрибутов, что и привязанные символы. Атрибутcopyможет использоваться с переменными, функциями или типами. Однако тип символа, к которому применяется атрибут (переменная или функция), должен соответствовать типу символа, на который ссылается аргумент. Атрибутcopyкопирует только синтаксические и семантические атрибуты, но не атрибуты, которые влияют на ссылку или видимость символа, такие какalias,visibility, илиweak. Атрибутdeprecatedтакже не копируется. См. Общие атрибуты функций. См. Общие атрибуты типов. deprecateddeprecated (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. Это позволяет запросить целочисленный или плавающий тип в соответствии с его шириной.
См. Машинные режимы в GNU Compiler Collection (GCC) Internals, чтобы увидеть список возможных ключевых слов для 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++, атрибут также означает, что член инициализируется, если класс сам инициализируется.
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описан в Общие атрибуты функций.
Далее: Атрибуты переменных ARC, Назад: Атрибуты переменных [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-9.5.0/gcc/Common-Variable-Attributes.html