Spec-Zone.ru › GCC 15

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 — это указатель на функцию, которая, подобно стандартной функции C calloc, возвращает объект, размер которого задаётся произведением аргументов 1 и 2; аналогично, malloc_ptr, подобно стандартной функции C malloc, возвращает объект, размер которого задаётся аргументом 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

Spec-Zone.ru

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