Spec-Zone.ru › GCC 11

Next: ARC Переменные Атрибуты, Up: Указание атрибутов переменных [Оглавление][Индекс]

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, подобного «warning: выравнивание 8 для 'struct foo' меньше 16». Компилятор также выдаёт предупреждение, подобное «warning: смещение '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-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 разместить переменную в общем хранилище. Атрибут 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. Это позволяет запросить целочисленный или с плавающей запятой тип в соответствии с его шириной.

См. Режимы машины в документации 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 или более поздней.

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 (что, возможно, приводит к сбросу свойства в какое-либо значение по умолчанию), но для которого получатель свойства никогда не сможет возвратить значение nil.

Далее: Атрибуты переменных ARC, Вверх: Указание атрибутов переменных [Содержание][Индекс]

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

Spec-Zone.ru

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