Spec-Zone.ru › GCC 9

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 должен быть целой константой, являющейся степенью двойки. Отсутствие аргумента 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 не вернётся нормально.

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.

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

Spec-Zone.ru

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