Spec-Zone.ru › GCC 12

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 задает минимальное выравнивание переменной или поля структуры, измеряемое в байтах. При указании 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 также может быть использован для функций (см. Общие атрибуты функций.)

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 также может быть использован для типов (см. Общие атрибуты типов.)

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 разместить переменную в хранилище «common». Атрибут nocommon просит сделать обратное — выделить для неё место непосредственно.

Эти атрибуты переопределяют значения, выбранные по умолчанию флагами -fno-common и -fcommon соответственно.

copy
copy (variable)

Атрибут copy применяет набор атрибутов, с которыми была объявлена переменная, к объявлению переменной, к которой применён атрибут. Атрибут предназначен для библиотек, которые определяют псевдонимы, которые ожидаются задавать тот же набор атрибутов, что и алиасированные символы. Атрибут 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 Compiler Collection (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 или загрузчиком программы. Неинициализация данных таким способом может сократить время запуска программы.

Этот атрибут специфичен для целевых платформ ELF и полагается на скрипт компоновщика, чтобы поместить секции с префиксом .noinit в нужное место.

persistent

Любые данные с атрибутом persistent не будут инициализированы кодом запуска времени выполнения C, но будут инициализированы загрузчиком программы. Это позволяет значению переменной «сохраняться» между перезагрузками процессора.

Этот атрибут специфичен для целевых платформ 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.

Далее: Атрибуты переменных ARC, Наверх: Атрибуты переменных [Оглавление][Индекс]

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

Spec-Zone.ru

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