Spec-Zone.ru › GCC 9

6.33.1 Атрибуты общих функций

Следующие атрибуты поддерживаются на большинстве целевых платформ.

alias ("target")

Атрибут alias заставляет объявление генерироваться как псевдоним для другого символа, который должен быть указан. Например,

void __f () { /* Do something. */; }
void f () __attribute__ ((weak, alias ("__f")));

определяет ‘f’ как слабый псевдоним для ‘__f’. В C++ необходимо использовать замаскированное имя для целевой платформы. Ошибка возникает, если ‘__f’ не определено в том же трансляционном блоке.

Этот атрибут требует поддержки ассемблера и объектных файлов и может быть недоступен на всех целевых платформах.

aligned
aligned (alignment)

Атрибут aligned задаёт минимальное выравнивание первого машинного кода функции в байтах. Если указано, alignment должно быть целым числом, являющимся степенью двойки. Если аргумент alignment не указан, используется идеальное выравнивание для целевой платформы. Для его определения можно использовать оператор __alignof__ (см. Выравнивание). Атрибут не оказывает влияния, если определение функции отсутствует в том же трансляционном блоке.

Атрибут нельзя использовать для уменьшения выравнивания функции, ранее объявленной с более строгим выравниванием; его можно только увеличить. Попытки сделать обратное приводят к диагностике ошибки. Некоторые целевые платформы задают минимальное значение выравнивания функций, большее единицы. На таких платформах указание менее строгого выравнивания игнорируется. Использование атрибута переопределяет эффект опции -falign-functions (см. Опции оптимизации) для данной функции.

Обратите внимание, что эффективность атрибутов aligned может быть ограничена внутренними ограничениями системного линкера и/или формата объектного файла. На некоторых системах линкер может выровнять функции только до определённого максимального выравнивания. (Для некоторых линков максимальное поддерживаемое выравнивание может быть очень малым.) Для получения дополнительной информации см. документацию вашего линкера.

Атрибут aligned также может применяться к переменным и полям (см. Атрибуты переменных).

alloc_align (position)

Атрибут alloc_align может применяться к функции, которая возвращает указатель и принимает как минимум один аргумент целочисленного или перечислимого типа. Он указывает, что возвращаемый указатель выровнен по границе, заданной аргументом функции в позиции position. Значимые значения выравнивания — степени двойки, большие единицы. Компилятор GCC использует эту информацию для улучшения анализа выравнивания указателей.

Параметр функции, обозначающий выравнивание, задаётся одним целочисленным константным аргументом, число которого является аргументом атрибута. Нумерация аргументов начинается с единицы.

Например,

void* my_memalign (size_t, size_t) __attribute__ ((alloc_align (1)));

объявляет, что my_memalign возвращает память с минимальным выравниванием, заданным параметром 1.

alloc_size (position)
alloc_size (position-1, position-2)

Атрибут alloc_size может применяться к функции, которая возвращает указатель и принимает как минимум один аргумент целочисленного или перечислимого типа. Он указывает, что возвращаемый указатель указывает на память, размер которой задаётся аргументом функции в позиции position-1 или произведением аргументов в позициях position-1 и position-2. Значимые размеры — положительные значения меньше PTRDIFF_MAX. GCC использует эту информацию для улучшения результатов __builtin_object_size.

Параметр(ы) функции, обозначающий(ие) размер, задаются одним или двумя целочисленными аргументами, переданными в атрибут. Заданный размер — это значение единственного аргумента функции или произведение двух аргументов функции. Нумерация аргументов начинается с единицы для обычных функций и с двойки для нестатических функций-членов в C++.

Например,

void* my_calloc (size_t, size_t) __attribute__ ((alloc_size (1, 2)));
void* my_realloc (void*, size_t) __attribute__ ((alloc_size (2)));

объявляет, что my_calloc возвращает память размера, заданного произведением параметров 1 и 2, и что my_realloc возвращает память размера, заданного параметром 2.

always_inline

Функции обычно не встраиваются, если не указана оптимизация. Для объявленных inline функций этот атрибут встраивает функцию независимо от любых других ограничений, которые обычно применяются к встраиванию. Невозможность встроить такую функцию диагностируется как ошибка. Обратите внимание, что если такая функция вызывается косвенно, компилятор может или не может встроить её в зависимости от уровня оптимизации, и невозможность встраивания косвенного вызова может или не может быть диагностирована.

artificial

Этот атрибут полезен для небольших встраиваемых обёртки, которые, по возможности, должны отображаться при отладке как единое целое. В зависимости от формата отладочных данных он либо помечает функцию как искусственную, либо использует расположение вызывающей функции для всех инструкций внутри встроенного тела.

assume_aligned (alignment)
assume_aligned (alignment, offset)

Атрибут assume_aligned может применяться к функции, которая возвращает указатель. Он указывает, что возвращаемый указатель выровнен по границе, заданной alignment. Если атрибут имеет два аргумента, второй аргумент — сдвиг невыравнивания offset. Значимые значения alignment — степени двойки, большие единицы. Значимые значения offset — больше нуля и меньше alignment.

Например,

void* my_alloc1 (size_t) __attribute__((assume_aligned (16)));
void* my_alloc2 (size_t) __attribute__((assume_aligned (32, 8)));

объявляет, что my_alloc1 возвращает указатели с выравниванием 16 байт, и что my_alloc2 возвращает указатель, значение которого при взятии по модулю 32 равно 8.

cold

Атрибут cold для функций используется для информирования компилятора о том, что функция вряд ли будет выполняться. Функция оптимизируется под размер, а не под скорость, и на многих целевых платформах она помещается в специальный подсекцию секции кода, так что все холодные функции располагаются близко друг к другу, улучшая локальность кода для нехолодных частей программы. Пути, ведущие к вызовам холодных функций в коде, отмечаются механизмом предсказания ветвлений как маловероятные. Поэтому полезно помечать функции, используемые для обработки маловероятных условий, таких как perror, как холодные, чтобы улучшить оптимизацию горячих функций, которые в редких случаях вызывают помеченные функции.

При наличии отслеживания профилей через -fprofile-use, холодные функции обнаруживаются автоматически, и этот атрибут игнорируется.

const

Вызовы функций, значение возвращаемого значения которых не зависит от изменений наблюдаемого состояния программы и которые не оказывают наблюдаемого воздействия на это состояние, кроме возвращения значения, могут быть оптимизированы, например, путём удаления общих подвыражений. Объявление таких функций с атрибутом const позволяет GCC избегать выдачи некоторых вызовов при многократных вызовах функции с одинаковыми значениями аргументов.

Например,

int square (int) __attribute__ ((const));

сообщает GCC, что последующие вызовы функции square с одинаковым значением аргумента могут быть заменены результатом первого вызова независимо от утверждений между ними.

Атрибут const запрещает функции читать объекты, влияющие на её возвращаемое значение между последовательными вызовами. Однако функции, объявленные с этим атрибутом, могут безопасно читать объекты, не изменяющие их возвращаемое значение, такие как константы, не изменяющиеся в процессе выполнения.

Атрибут const накладывает большие ограничения на определение функции, чем аналогичный атрибут pure. Объявление одной и той же функции с атрибутами const и pure диагностируется как ошибка. Поскольку константная функция не может иметь никаких наблюдаемых побочных эффектов, для неё не имеет смысла возвращать void. Объявление такой функции диагностируется.

Обратите внимание, что функция, имеющая указательные аргументы и проверяющая данные, на которые они указывают, не должна быть объявлена const, если данные, на которые указывают эти указатели, могут измениться между последовательными вызовами функции. В общем случае, поскольку функция не может различать данные, которые могут измениться, от данных, которые не могут, константные функции никогда не должны принимать указатели или, в C++, ссылки в качестве аргументов. Аналогично, функция, которая вызывает неконстантную функцию, обычно не должна быть константной.

constructor
destructor
constructor (priority)
destructor (priority)

Атрибут constructor заставляет функцию вызываться автоматически перед тем, как выполнение войдёт в main (). Аналогично, атрибут destructor заставляет функцию вызываться автоматически после завершения main () или вызова exit (). Функции с этими атрибутами полезны для инициализации данных, которые используются неявно во время выполнения программы.

На некоторых целевых платформах атрибуты также принимают целочисленный аргумент для задания приоритета, чтобы управлять порядком выполнения функций-конструкторов и деструкторов. Конструктор с меньшим приоритетом выполняется перед конструктором с большим приоритетом; обратная связь существует для деструкторов. Поэтому, если у вас есть конструктор, который выделяет ресурс, и деструктор, который освобождает тот же ресурс, обе функции обычно имеют одинаковый приоритет. Приоритеты для конструкторов и деструкторов совпадают с приоритетами для функций пространства имён в C++ (см. Атрибуты C++). Однако в настоящее время порядок вызова конструкторов для объектов C++ со статическим сроком жизни и функций, помеченных атрибутом constructor, не определён. При смешанных объявлениях атрибут init_priority может использоваться для навязывания определённого порядка.

Использование аргументных форм атрибутов constructor и destructor на платформах, где эта функция не поддерживается, приводит к ошибке.

copy
copy (function)
END_OF_DOCUMENT_MARKER

Атрибут copy применяет набор атрибутов, с помощью которых была объявлена function, к объявлению функции, к которой этот атрибут применяется. Этот атрибут предназначен для библиотек, которые определяют псевдонимы или функции разрешения, которые должны указывать тот же набор атрибутов, что и их целевые функции. Атрибут copy может использоваться с функциями, переменными или типами. Однако тип символа, к которому применяется атрибут (либо функция, либо переменная), должен соответствовать типу символа, на который ссылается аргумент. Атрибут copy копирует только синтаксические и семантические атрибуты, но не атрибуты, влияющие на привязку или видимость символа, такие как alias, visibility, или weak. Атрибут deprecated также не копируется. См. Общие атрибуты типов. См. Общие атрибуты переменных.

Например, макрос StrongAlias ниже использует атрибуты alias и copy для определения псевдонима под названием alloc для функции allocate, объявленной с атрибутами alloc_size, malloc и nothrow. Благодаря оператору __typeof__ псевдоним имеет тот же тип, что и целевая функция. В результате применения атрибута copy псевдоним также разделяет те же атрибуты, что и целевая функция.

#define StrongAlias(TargetFunc, AliasDecl)  \
  extern __typeof__ (TargetFunc) AliasDecl  \
    __attribute__ ((alias (#TargetFunc), copy (TargetFunc)));

extern __attribute__ ((alloc_size (1), malloc, nothrow))
  void* allocate (size_t);
StrongAlias (allocate, alloc);
deprecated
deprecated (msg)

Атрибут deprecated приводит к появлению предупреждения, если функция используется где-либо в исходном файле. Это полезно при идентификации функций, которые, как ожидается, будут удалены в будущей версии программы. Предупреждение также включает местоположение объявления устаревшей функции, что позволяет пользователям легко найти дополнительную информацию о причинах устаревания функции или о том, что нужно сделать вместо неё. Обратите внимание, что предупреждения появляются только при использовании:

int old_fn () __attribute__ ((deprecated));
int old_fn ();
int (*fn_ptr)() = old_fn;

приводит к предупреждению на строке 3, но не на строке 2. Необязательный аргумент msg, который должен быть строкой, выводится в предупреждении, если он присутствует.

Атрибут deprecated также может использоваться для переменных и типов (см. Атрибуты переменных, см. Атрибуты типов).

Сообщение, прикреплённое к атрибуту, зависит от установки опции -fmessage-length.

error ("message")
warning ("message")

Если атрибут error или warning используется в объявлении функции, а вызов этой функции не удаляется при устранении неиспользуемого кода или других оптимизациях, генерируется ошибка или предупреждение (соответственно), включающее message. Это полезно для проверки во время компиляции, особенно совместно с __builtin_constant_p и встроенными функциями, где проверка аргументов встроенной функции невозможна с помощью приёмов extern char [(condition) ? 1 : -1];.

Хотя возможно оставить функцию неопределённой и тем самым вызвать ошибку компоновки (для определения функции с сообщением в разделе .gnu.warning*), при использовании этих атрибутов проблема диагностируется на более ранней стадии и с точным указанием места вызова, даже при наличии встроенных функций или при отсутствии отладки.

externally_visible

Этот атрибут, прикреплённый к глобальной переменной или функции, аннулирует действие командной опции -fwhole-program, поэтому объект остаётся видимым вне текущей единицы компиляции.

Если -fwhole-program используется вместе с -flto, а gold используется в качестве плагина компоновщика, атрибуты externally_visible автоматически добавляются к функциям (но не переменным, из-за текущей проблемы gold ), к которым осуществляется доступ вне объектов LTO в соответствии с файлом разрешения, сгенерированным gold. Для других компоновщиков, которые не могут генерировать файл разрешения, явные атрибуты externally_visible по-прежнему необходимы.

flatten

Как правило, встраивание в функцию ограничено. Для функции, помеченной этим атрибутом, каждый вызов внутри этой функции встраивается, если это возможно. Функции, объявленные с атрибутом noinline и аналогичные, не встраиваются. Будет ли сама функция рассматриваться для встраивания, зависит от её размера и текущих параметров встраивания.

format (archetype, string-index, first-to-check)

Атрибут format указывает, что функция принимает аргументы типа printf, scanf, strftime или strfmon, которые должны быть проверены на тип относительно строки формата. Например, объявление:

extern int
my_printf (void *my_object, const char *my_format, ...)
      __attribute__ ((format (printf, 2, 3)));

приводит к проверке компилятором аргументов в вызовах к my_printf на соответствие строке формата printf стиля my_format.

Параметр archetype определяет, как интерпретируется строка формата, и должен быть printf, scanf, strftime, gnu_printf, gnu_scanf, gnu_strftime или strfmon. (Вы также можете использовать __printf__, __scanf__, __strftime__ или __strfmon__.) На целевых платформах MinGW также присутствуют ms_printf, ms_scanf, и ms_strftime. Значения archetype, такие как printf, относятся к форматам, поддерживаемым системной библиотекой C, в то время как значения, начинающиеся с «gnu_», всегда относятся к форматам, поддерживаемым GNU C Library. На целевых платформах Microsoft Windows значения, начинающиеся с «ms_», относятся к форматам, поддерживаемым библиотекой msvcrt.dll. Параметр string-index указывает, какой аргумент является аргументом строки формата (начиная с 1), а first-to-check — номер первого аргумента для проверки относительно строки формата. Для функций, где аргументы недоступны для проверки (например, vprintf), укажите третий параметр как ноль. В этом случае компилятор проверяет только строку формата на соответствие. Для форматов strftime третий параметр должен быть равен нулю. Поскольку нестатические методы C++ имеют неявный аргумент this, аргументы таких методов должны быть пронумерованы с двух, а не с одного, при указании значений для string-index и first-to-check.

В приведённом примере строка формата (my_format) является вторым аргументом функции my_print, а проверяемые аргументы начинаются с третьего, поэтому правильные параметры для атрибута формата — 2 и 3.

Атрибут format позволяет идентифицировать собственные функции, принимающие строки формата в качестве аргументов, чтобы GCC мог проверять вызовы этих функций на наличие ошибок. Компилятор всегда (если не используется -ffreestanding или -fno-builtin) проверяет форматы для функций стандартной библиотеки printf, fprintf, sprintf, scanf, fscanf, sscanf, strftime, vprintf, vfprintf и vsprintf, когда такие предупреждения запрашиваются (с помощью -Wformat), поэтому нет необходимости изменять заголовочный файл stdio.h. В режиме C99 также проверяются функции snprintf, vsnprintf, vscanf, vfscanf и vsscanf. За исключением строго соответствующих режимов C, также проверяется функция X/Open strfmon, а также printf_unlocked и fprintf_unlocked. См. Опции, контролирующие диалект C.

Для диалектов Objective-C, NSString (или __NSString__) распознаётся в том же контексте. Объявления, включающие эти атрибуты формата, анализируются на правильность синтаксиса, однако результат проверки таких строк формата ещё не определён и не выполняется этой версией компилятора.

Целевая платформа может также предоставить дополнительные типы проверок формата. См. Проверки формата, специфичные для конкретных целевых машин.

format_arg (string-index)

Атрибут format_arg указывает, что функция принимает один или несколько форматов строк для функции стиля printf, scanf, strftime или strfmon и изменяет ее (например, для перевода на другой язык), чтобы результат можно было передать функции стиля printf, scanf, strftime или strfmon (с оставшимися аргументами функции форматирования такими же, как и для немодифицированной строки). Несколько атрибутов format_arg могут быть применены к одной функции, каждый из которых обозначает отдельный параметр в качестве строки форматирования. Например, объявление:

extern char *
my_dgettext (char *my_domain, const char *my_format)
      __attribute__ ((format_arg (2)));

заставляет компилятор проверять аргументы в вызовах функции типа printf, scanf, strftime или strfmon, где аргумент строки форматирования является вызовом функции my_dgettext, для согласованности с аргументом строки форматирования my_format. Если атрибут format_arg не был указан, компилятор мог бы определить только то, что аргумент строки форматирования не является константой; это сгенерировало бы предупреждение при использовании -Wformat-nonliteral, но вызовы не могли быть проверены без атрибута.

При вызовах функции, объявленной с более чем одним атрибутом format_arg, каждый из которых имеет разное значение аргумента, соответствующие фактические аргументы функции проверяются на соответствие всем строкам форматирования, обозначенным атрибутами. Эта возможность предназначена для поддержки семейства функций GNU ngettext.

Параметр string-index указывает, какой аргумент является аргументом строки форматирования (начиная с единицы). Поскольку у нестатических методов C++ есть неявный аргумент this, аргументы таких методов должны быть пронумерованы начиная со второго.

Атрибут format_arg позволяет идентифицировать собственные функции, которые изменяют строки форматирования, чтобы GCC мог проверять вызовы функций типа printf, scanf, strftime или strfmon, где операнды являются вызовом одной из ваших собственных функций. Компилятор всегда обрабатывает gettext, dgettext и dcgettext таким образом, за исключением случаев, когда поддержка строгого ISO C запрашивается с помощью -ansi или соответствующего параметра -std, или используется -ffreestanding или -fno-builtin. См. Параметры, управляющие диалектом C.

Для диалектов Objective-C атрибут format-arg может ссылаться на NSString ссылку для совместимости с атрибутом format выше.

Целевой процессор может также разрешить дополнительные типы в атрибутах format-arg. См. Проверки форматирования, специфичные для конкретных целевых машин.

gnu_inline

Этот атрибут следует использовать с функцией, которая также объявлена с ключевым словом inline. Он сообщает GCC обрабатывать функцию так, как будто она определена в режиме gnu90, даже при компиляции в режиме C99 или gnu99.

Если функция объявлена extern, то это определение функции используется только для встраивания. Ни в коем случае функция не компилируется как самостоятельная функция, даже если вы явно берете ее адрес. Такой адрес становится внешней ссылкой, как будто вы только объявили функцию и не определили ее. Это почти имеет эффект макроса. Способ использования заключается в размещении определения функции в файле заголовков с этим атрибутом и размещении другой копии функции без extern в файле библиотеки. Определение в файле заголовков приводит к тому, что большинство вызовов функции встраиваются. Если какие-либо использования функции остаются, они ссылаются на единственную копию в библиотеке. Обратите внимание, что два определения функций не обязательно должны быть точно одинаковыми, хотя если они не имеют одинакового эффекта, ваша программа может вести себя странно.

В языке C, если функция не является ни extern, ни static, то функция компилируется как самостоятельная функция, а также встраивается по возможности.

Это то, как GCC традиционно обрабатывал функции, объявленные inline. Поскольку ISO C99 определяет другую семантику для inline, этот атрибут функции предоставляется как переходная мера и как полезная функция сама по себе. Этот атрибут доступен в GCC 4.1.3 и более поздних версиях. Он доступен, если определены макросы препроцессора __GNUC_GNU_INLINE__ или __GNUC_STDC_INLINE__. См. Функция Inline - такая же быстрая, как макрос.

В C++, этот атрибут никак не зависит от extern, но для активации его специального поведения всё равно требуется ключевое слово inline.

hot

Атрибут hot для функции используется для информирования компилятора о том, что функция является горячей точкой компилируемой программы. Функция оптимизируется более агрессивно, а на многих целевых платформах она помещается в специальный подсекции секции кода, чтобы все горячие функции располагались близко друг к другу, улучшая локальность.

Когда доступна обратная связь от профилирования, через -fprofile-use, горячие функции автоматически обнаруживаются, и этот атрибут игнорируется.

ifunc ("resolver")

Атрибут ifunc используется для маркировки функции как косвенной функции, используя расширение типа символа STT_GNU_IFUNC к стандарту ELF. Это позволяет динамически определить значение символа во время загрузки и выбрать оптимизированную версию процедуры для конкретного процессора или других системных характеристик, определённых тогда. Чтобы использовать этот атрибут, сначала определите доступные реализующие функции и функцию-разрешитель, возвращающую указатель на выбранную реализующую функцию. Объявления реализующих функций должны соответствовать API функции, которую они реализуют. Функция-разрешитель должна быть объявлена как функция без аргументов, возвращающая указатель на функцию того же типа, что и реализующая. Например:

void *my_memcpy (void *dst, const void *src, size_t len)
{
  …
  return dst;
}

static void * (*resolve_memcpy (void))(void *, const void *, size_t)
{
  return my_memcpy; // we will just always select this routine
}

Экспортируемый файл заголовков, объявляющий функцию, вызываемую пользователем, содержал бы:

extern void *memcpy (void *, const void *, size_t);

что позволяет пользователю вызывать memcpy как обычную функцию, не зная фактической реализации. Наконец, косвенная функция должна быть определена в том же модуле трансляции, что и функция-разрешитель:

void *memcpy (void *, const void *, size_t)
     __attribute__ ((ifunc ("resolve_memcpy")));

В C++, атрибут ifunc принимает строку, которая является отформатированным именем функции-разрешителя. C++ функция-разрешитель для нестатического метода класса C должна быть объявлена для возврата указателя на нестатическую функцию, принимающую указатель на C в качестве первого аргумента, а затем те же аргументы, что и у реализующей функции. G++ проверяет сигнатуры обеих функций и выводит предупреждение -Wattribute-alias при несовпадениях. Для подавления предупреждения о необходимости преобразования указателя на реализующий член функции в тип соответствующей нестатической функции используйте опцию -Wno-pmf-conversions. Например:

class S
{
private:
  int debug_impl (int);
  int optimized_impl (int);

  typedef int Func (S*, int);

  static Func* resolver ();
public:

  int interface (int);
};

int S::debug_impl (int) { /* … */ }
int S::optimized_impl (int) { /* … */ }

S::Func* S::resolver ()
{
  int (S::*pimpl) (int)
    = getenv ("DEBUG") ? &S::debug_impl : &S::optimized_impl;

  // Cast triggers -Wno-pmf-conversions.
  return reinterpret_cast<Func*>(pimpl);
}

int S::interface (int) __attribute__ ((ifunc ("_ZN1S8resolverEv")));

Косвенные функции не могут быть слабыми. Для использования этой функции требуются Binutils версии 2.20.1 или выше и GNU C Library версии 2.11.1 или выше.

interrupt
interrupt_handler

Многие бэкэнды GCC поддерживают атрибуты для указания того, что функция является обработчиком прерываний, что сообщает компилятору сгенерировать последовательности входа и выхода из функции, которые отличаются от последовательностей для обычных функций. Точная синтаксис и поведение зависят от целевой платформы; подробности см. в следующих разделах.

leaf

Вызовы внешних функций с этим атрибутом должны возвращаться в текущий модуль компиляции только через возвращение или обработку исключений. В частности, функция-лист не может вызывать обратные вызовы, переданные ей из текущего модуля компиляции, напрямую вызывать функции, экспортированные модулем, или longjmp в модуль. Функции-листья все еще могут вызывать функции из других модулей компиляции и, следовательно, они не обязательно являются функциями-листьями в том смысле, что они не содержат никаких вызовов функций вообще.

Этот атрибут предназначен для функций библиотек для повышения эффективности анализа потоков данных. Компилятор принимает подсказку о том, что любые данные, не покидающие текущий модуль компиляции, не могут быть использованы или изменены функцией-листом. Например, функция sin является функцией-листом, но qsort нет.

Обратите внимание, что функции-листья могут косвенно запускать обработчик сигналов, определённый в текущем модуле компиляции, который использует статические переменные. Аналогично, при наличии ленивого разрешения символов функции-листья могут вызывать косвенные функции, функция-разрешитель или реализующая функция которых определена в текущем модуле компиляции и использует статические переменные. Нет способа, соответствующего стандартам, написать такой обработчик сигналов, функцию-разрешитель или реализующую функцию, и всё, что вы можете сделать, это удалить атрибут leaf или пометить все такие статические переменные volatile. Наконец, для систем на основе ELF, поддерживающих интерпозицию символов, следует быть внимательным, чтобы функции, определенные в текущем модуле компиляции, не вызывали неожиданной интерпозиции других символов на основе определённого режима стандарта и определённых макросов тестов функций; в противном случае будет добавлен непреднамеренный обратный вызов.

Атрибут не оказывает влияния на функции, определенные в текущем модуле компиляции. Это позволяет легко объединять несколько модулей компиляции в один, например, с помощью оптимизации на этапе компоновки. По этой причине атрибут не разрешается для типов для аннотирования косвенных вызовов.

malloc

Это сообщает компилятору, что функция подобна malloc, т.е., что указатель P, возвращаемый функцией, не может быть алиасом для любого другого указателя, действительного на момент возврата функции, и кроме того, в любом хранилище, адресуемом P, не встречаются указатели на валидные объекты.

Использование этого атрибута может улучшить оптимизацию. Компилятор предполагает, что функция с этим атрибутом возвращает не нуль в большинстве случаев. Функции, подобные malloc и calloc, обладают этим свойством, потому что они возвращают указатель на неинициализированное или обнуленное хранилище. Однако функции, подобные realloc, не обладают этим свойством, поскольку они могут возвращать указатель на хранилище, содержащее указатели.

no_icf

Этот атрибут функции предотвращает слияние функций с другой семантически эквивалентной функцией.

no_instrument_function

Если указаны какие-либо из -finstrument-functions, -p или -pg, генерируются функции профилирования для вызова функций в начале и конце большинства функций, скомпилированных пользователем. Функции с этим атрибутом не будут так проинструментированы.

no_profile_instrument_function

Атрибут no_profile_instrument_function функций используется для того, чтобы сообщить компилятору, что он не должен обрабатывать никакое профилирование, основанное на оптимизации кода.

no_reorder

Не переупорядочивайте функции или переменные, помеченные no_reorder, друг относительно друга или инструкции ассемблера верхнего уровня в исполняемом файле. Фактический порядок в программе будет зависеть от командной строки компоновщика. Статические переменные, помеченные таким образом, также не удаляются. Это имеет аналогичный эффект, как опция -fno-toplevel-reorder, но применяется только к помеченным символам.

no_sanitize ("sanitize_option")

Атрибут no_sanitize для функций используется для того, чтобы сообщить компилятору, что он не должен выполнять очистку всех опций, упомянутых в sanitize_option. Список допустимых значений для опции -fsanitize можно указать.

void __attribute__ ((no_sanitize ("alignment", "object-size")))
f () { /* Do something. */; }
void __attribute__ ((no_sanitize ("alignment,object-size")))
g () { /* Do something. */; }
no_sanitize_address
no_address_safety_analysis

Атрибут no_sanitize_address для функций используется для того, чтобы сообщить компилятору, что он не должен инструментировать обращения к памяти в функции при компиляции с опцией -fsanitize=address. Атрибут no_address_safety_analysis является устаревшим алиасом атрибута no_sanitize_address, новый код должен использовать no_sanitize_address.

no_sanitize_thread

Атрибут no_sanitize_thread для функций используется для того, чтобы сообщить компилятору, что он не должен инструментировать обращения к памяти в функции при компиляции с опцией -fsanitize=thread.

no_sanitize_undefined

Атрибут no_sanitize_undefined для функций используется для того, чтобы сообщить компилятору, что он не должен проверять неопределённое поведение в функции при компиляции с опцией -fsanitize=undefined.

no_split_stack

Если указана -fsplit-stack, функции имеют небольшой пролог, который определяет, следует ли разделять стек. Функции с атрибутом no_split_stack не имеют этого пролога и, следовательно, могут работать только с небольшим объёмом доступного стека.

no_stack_limit

Этот атрибут локально переопределяет опции командной строки -fstack-limit-register и -fstack-limit-symbol; он имеет эффект отключения проверки предела стека в функции, к которой он применяется.

noclone

Этот атрибут функции предотвращает рассмотрение функции для клонирования — механизма, который создаёт специализированные копии функций и который (в настоящее время) выполняется межпроцедурной постоянной простановкой.

noinline

Этот атрибут функции предотвращает рассмотрение функции для встраивания. Если функция не имеет побочных эффектов, существуют оптимизации, помимо встраивания, которые приводят к тому, что вызовы функций исключаются, хотя вызов функции активен. Чтобы предотвратить исключение таких вызовов, поместите

asm ("");

(см. Расширенный ассемблер) в вызываемой функции, чтобы служить особым побочным эффектом.

noipa

Отключить межпроцедурные оптимизации между функцией с этим атрибутом и её вызывающими функциями, как если бы тело функции было недоступно при оптимизации вызывающих функций, а вызывающие функции были недоступны при оптимизации тела. Этот атрибут подразумевает атрибуты noinline, noclone и no_icf. Однако, этот атрибут не эквивалентен комбинации других атрибутов, потому что его цель — подавить существующие и будущие оптимизации, использующие межпроцедурный анализ, включая те, которые не имеют подходящего атрибута для их отключения индивидуально. Этот атрибут поддерживается в основном для целей тестирования компилятора.

nonnull
nonnull (arg-index, …)

Атрибут nonnull может быть применён к функции, которая принимает как минимум один аргумент типа указателя. Он указывает, что ссылочные аргументы должны быть указателями, отличными от нуля. Например, объявление:

extern void *
my_memcpy (void *dest, const void *src, size_t len)
        __attribute__((nonnull (1, 2)));

приводит к тому, что компилятор проверяет, что при вызовах функции my_memcpy аргументы dest и src являются указателями, отличными от нуля. Если компилятор определяет, что в аргумент, помеченный как «не нулевой», передаётся нулевой указатель, и опция -Wnonnull включена, выводится предупреждение. См. Опции предупреждений. Если опция -fno-delete-null-pointer-checks не отключена, компилятор может также выполнить оптимизации, основываясь на том, что некоторые аргументы функций не могут быть нулевыми. Кроме того, может быть указана опция -fisolate-erroneous-paths-attribute, чтобы GCC преобразовывал вызовы с нулевыми аргументами в функции, отличные от нуля, в ловушки. См. Опции оптимизации.

Если атрибуту nonnull не задан arg-index, все аргументы-указатели отмечаются как отличные от нуля. Для иллюстрации, следующее объявление эквивалентно предыдущему примеру:

extern void *
my_memcpy (void *dest, const void *src, size_t len)
        __attribute__((nonnull));
noplt

Атрибут noplt является аналогом опции -fno-plt. Вызовы функций, помеченных этим атрибутом в позиционно-независимом коде, не используют PLT.

/* Externally defined function foo.  */
int foo () __attribute__ ((noplt));

int
main (/* … */)
{
  /* … */
  foo ();
  /* … */
}

Атрибут noplt для функции foo сообщает компилятору, что функция foo определена внешне и что вызов foo должен избегать PLT в позиционно-независимом коде.

В позиционно-зависимом коде некоторые целевые платформы также преобразуют вызовы функций, которые отмечены как не использующие PLT, в использование GOT вместо него.

noreturn

Некоторые стандартные функции библиотеки, такие как abort и exit, не могут возвращать значения. GCC знает об этом автоматически. Некоторые программы определяют свои собственные функции, которые никогда не возвращаются. Вы можете объявить их noreturn , чтобы сообщить об этом компилятору. Например,

void fatal () __attribute__ ((noreturn));

void
fatal (/* … */)
{
  /* … */ /* Print error message. */ /* … */
  exit (1);
}

Ключевое слово noreturn сообщает компилятору, что fatal не может вернуть значение. Он может затем оптимизировать, не учитывая то, что произойдёт, если fatal когда-либо вернёт значение. Это делает код немного лучше. Что более важно, это помогает избежать ложных предупреждений о неопределённых переменных.

Ключевое слово noreturn не влияет на исключительный путь, когда это применимо: функция, помеченная noreturn, всё ещё может вернуть вызывающей функции, выбросив исключение или вызвав longjmp.

Для сохранения трассировок GCC никогда не преобразует вызовы функций noreturn в хвостовые вызовы.

Не предполагайте, что регистры, сохранённые вызывающей функцией, восстанавливаются перед вызовом функции noreturn.

Не имеет смысла, чтобы функция noreturn имела тип возвращаемого значения, отличный от void.

nothrow

Атрибут nothrow используется для того, чтобы сообщить компилятору, что функция не может бросить исключение. Например, большинство функций в стандартной C-библиотеке гарантированно не выбрасывают исключения, за исключением qsort и bsearch, которые принимают аргументы указателей на функции.

optimize (level, …)
optimize (string, …)

Атрибут optimize используется для указания того, что функция должна быть скомпилирована с разными опциями оптимизации, чем указанные в командной строке. Допустимыми аргументами являются постоянные неотрицательные целые числа и строки. Каждый числовой аргумент определяет уровень оптимизации level. Каждый аргумент string состоит из одной или нескольких подстрок, разделённых запятыми. Каждая подстрока, начинающаяся с буквы O, относится к опции оптимизации, например, -O0 или -Os. Другие подстроки рассматриваются как суффиксы к префиксу -f , совместно образуя имя опции оптимизации. См. Опции оптимизации.

‘#pragma GCC optimize’ можно использовать для установки опций оптимизации для более чем одной функции. См. Опции оптимизации, специфичные для функций для подробностей о препроцессорной директиве.

Предоставление нескольких строк в качестве аргументов, разделённых запятыми, для указания нескольких опций, эквивалентно разделению суффиксов опций запятой (‘,’) внутри одной строки. Пробелы внутри строк не допускаются.

Не каждая опция оптимизации, начинающаяся с префикса -f, указанная в атрибуте, обязательно оказывает влияние на функцию. Атрибут optimize следует использовать только в отладочных целях. Он не подходит для кода в рабочей среде.

patchable_function_entry

В случае, если сегмент текста целевой платформы может быть сделан доступным для записи во время выполнения любыми средствами, добавление нескольких инструкций NOP в начало функции может использоваться для универсального инструментария инструментирования.

Атрибут функции patchable_function_entry может быть использован для изменения количества инструкций NOP на любое желаемое значение. Синтаксис с двумя значениями такой же, как и для переключателя командной строки -fpatchable-function-entry=N,M, генерирующего N инструкций NOP, где точка входа в функцию находится перед M-й инструкцией NOP. M по умолчанию равно 0, если опущено (т.е. точка входа в функцию находится перед первой инструкцией NOP).

Если точки входа в изменяемые функции включены глобально с помощью опции командной строки -fpatchable-function-entry=N,M, вам необходимо отключить инструментирование всех функций, которые являются частью инструментария инструментирования, с помощью атрибута patchable_function_entry (0) , чтобы предотвратить рекурсию.

pure

Вызовы функций, не оказывающих заметного влияния на состояние программы, кроме возвращения значения, могут быть оптимизированы, например, путём исключения общих подвыражений. Объявление таких функций с атрибутом pure позволяет GCC избегать вызова функций при многократных вызовах с одинаковыми аргументами.

Атрибут pure запрещает функции изменять состояние программы, которое можно наблюдать иными способами, кроме проверки значения возврата функции. Тем не менее, функции, объявленные с атрибутом pure могут безопасно считывать любые непеременные объекты и изменять значения объектов таким образом, чтобы это не повлияло на их значение возврата или наблюдаемое состояние программы.

Например,

int hash (char *) __attribute__ ((pure));

сообщает GCC, что последующие вызовы функции hash с той же строкой могут быть заменены результатом первого вызова при условии, что состояние программы, наблюдаемое hash, включая содержимое массива, не изменяется между вызовами. Несмотря на то, что hash принимает аргумент указателя на не-const, она не должна изменять массив, на который он указывает, или любой другой объект, значение которого может зависеть от остальной части программы. Тем не менее, вызывающая сторона может безопасно изменять содержимое массива между последовательными вызовами функции (это действие отключает оптимизацию). Это ограничение также применяется к объектам-членам, на которые указывает указатель this в нестатических членских функциях C++.

Некоторые распространённые примеры чистых функций — strlen или memcmp. Интересные нечистые функции — функции с бесконечными циклами или те, которые зависят от переменных объектов памяти или других системных ресурсов, которые могут изменяться между последовательными вызовами (например, стандартная C функция feof в многопоточной среде).

Атрибут pure накладывает подобные, но более слабые ограничения на определение функции, чем атрибут const. pure позволяет функции считывать любую непеременную память, даже если она изменяется между последовательными вызовами функции. Объявление одной и той же функции с атрибутами pure и const приводит к ошибке. Поскольку чистая функция не может иметь побочных эффектов, нет смысла для такой функции возвращать void. Объявление такой функции приводит к ошибке.

returns_nonnull

Атрибут returns_nonnull указывает, что значение возврата функции должно быть указателем на не-NULL. Например, объявление:

extern void *
mymalloc (size_t len) __attribute__((returns_nonnull));

позволяет компилятору оптимизировать вызывающую сторону, зная, что значение возврата никогда не будет нулевым.

returns_twice

Атрибут returns_twice сообщает компилятору, что функция может возвращать значение более одного раза. Компилятор гарантирует, что все регистры пусты до вызова такой функции, и выводит предупреждение о переменных, которые могут быть изменены после второго возврата из функции. Примеры таких функций — setjmp и vfork. Соответствующая функция типа longjmp, если она существует, может потребовать маркировки атрибутом noreturn.

section ("section-name")

Обычно компилятор размещает сгенерированный код в разделе text. Однако иногда вам нужны дополнительные разделы, или вам нужно, чтобы определённые функции появлялись в специальных разделах. Атрибут section указывает, что функция находится в определённом разделе. Например, объявление:

extern void foobar (void) __attribute__ ((section ("bar")));

размещает функцию foobar в разделе bar.

Некоторые форматы файлов не поддерживают произвольные разделы, поэтому атрибут section недоступен на всех платформах. Если вам нужно отобразить всё содержимое модуля в определённом разделе, воспользуйтесь возможностями компоновщика.

sentinel
sentinel (position)

Этот атрибут функции указывает, что аргумент в вызове функции ожидается как явный NULL. Атрибут действителен только для функций с переменным числом аргументов. По умолчанию ожидается, что сигнальная точка будет последним аргументом вызова функции. Если необязательный аргумент position указан в атрибуте, сигнальная точка должна быть расположена в позиции position, считая от конца списка аргументов.

__attribute__ ((sentinel))
is equivalent to
__attribute__ ((sentinel(0)))

Атрибут автоматически устанавливается с позицией 0 для встроенных функций execl и execlp. Встроенная функция execle имеет атрибут, установленный с позицией 1.

Действительной NULL в этом контексте является ноль с любым типом указателя объекта. Если ваша система определяет макрос NULL с типом целого числа, вам необходимо добавить явное приведение типа. Во время установки GCC заменяет системный заголовочный файл <stddef.h> копией, которая соответствующим образом переопределяет NULL.

Предупреждения о пропущенных или неправильных сигнальных точках включаются с помощью -Wformat.

simd
simd("mask")

Этот атрибут позволяет создавать одну или несколько версий функций, которые могут обрабатывать несколько аргументов с использованием инструкций SIMD из одного вызова. Указание этого атрибута позволяет компилятору предположить, что такие версии доступны во время компоновки (приведены в том же или другом модуле трансляции). Сгенерированные версии зависят от целевой платформы и описаны в соответствующем документе Vector ABI. Для целевой платформы x86_64 этот документ можно найти здесь.

Необязательный аргумент mask может иметь значение notinbranch или inbranch, и инструктирует компилятор сгенерировать не-маскированные или маскированные клоны соответственно. По умолчанию генерируются все клоны.

Если атрибут указан, и #pragma omp declare simd присутствует в объявлении, и переключатель -fopenmp или -fopenmp-simd указан, то атрибут игнорируется.

stack_protect

Этот атрибут добавляет код защиты стека к функции, если установлены флаги -fstack-protector, -fstack-protector-strong или -fstack-protector-explicit.

target (string, …)

Несколько целевых бэкендов реализуют атрибут target для указания того, что функция должна быть скомпилирована с разными целевыми параметрами, чем указано в командной строке. В качестве аргументов можно указать одну или несколько строк. Каждая строка состоит из одного или нескольких разделителей запятой суффиксов префикса -m, совместно формирующих имя зависящей от машины опции. См. Параметры, зависящие от модели машины.

Атрибут target может использоваться, например, для компиляции функции с другим ISA (архитектурой набора инструкций), отличным от значения по умолчанию. ‘#pragma GCC target’ можно использовать для указания опций, специфичных для целевой платформы, для более чем одной функции. См. Прагмы опций, специфичные для функции, для получения подробной информации.

Например, в x86 вы можете объявить одну функцию с атрибутом target("sse4.1,arch=core2") и другую с target("sse4a,arch=amdfam10"). Это эквивалентно компиляции первой функции с опциями -msse4.1 и -march=core2, а второй функции с опциями -msse4a и -march=amdfam10. Вам нужно убедиться, что функция вызывается только на машине, которая поддерживает конкретный ISA, для которого она скомпилирована (например, с помощью cpuid в x86 для определения используемых битов функций и семейства архитектуры).

int core2_func (void) __attribute__ ((__target__ ("arch=core2")));
int sse3_func (void) __attribute__ ((__target__ ("sse3")));

Предоставление нескольких строк в качестве аргументов, разделённых запятыми, для указания нескольких опций, эквивалентно разделению суффиксов опций запятой (‘,’) внутри одной строки. Пробелы внутри строк запрещены.

Поддерживаемые опции специфичны для каждой целевой платформы; обратитесь к Атрибуты функций x86, Атрибуты функций PowerPC, Атрибуты функций ARM, Атрибуты функций AArch64, Атрибуты функций Nios II и Атрибуты функций S/390 для получения подробной информации.

target_clones (options)

Атрибут target_clones используется для указания того, что функция должна быть клонирована в несколько версий, скомпилированных с различными целевыми параметрами, чем указано в командной строке. Поддерживаемые параметры и ограничения такие же, как и для атрибута target.

Например, в x86 вы могли бы скомпилировать функцию с target_clones("sse4.1,avx"). GCC создаст два клонирования функций, один скомпилированный с -msse4.1, а другой с -mavx.

На PowerPC вы можете скомпилировать функцию с target_clones("cpu=power9,default"). GCC создаст два клонирования функций, один скомпилированный с -mcpu=power9, а другой с параметрами по умолчанию. GCC должен быть настроен на использование GLIBC 2.23 или новее, чтобы использовать атрибут target_clones.

Он также создаёт функцию-резолвер (см. атрибут ifunc выше), которая динамически выбирает клон, подходящий для текущей архитектуры. Резолвер создаётся только в случае использования функции с атрибутом target_clones.

unused

Этот атрибут, прикреплённый к функции, означает, что функция может быть неиспользуемой. GCC не выводит предупреждение для этой функции.

used

Этот атрибут, прикреплённый к функции, означает, что код должен быть сгенерирован для функции, даже если функция не упоминается. Это полезно, например, когда функция упоминается только в встроенном ассемблере.

Если применить его к членской функции шаблона класса C++, то это также означает, что функция будет инстанцирована, если сам класс инстанцирован.

visibility ("visibility_type")

Этот атрибут влияет на связь объявления, к которому он прикреплён. Он может применяться к переменным (см. Общие атрибуты переменных) и типам (см. Общие атрибуты типов), а также к функциям.

Поддерживаются четыре значения visibility_type: default, hidden, protected или internal.

void __attribute__ ((visibility ("protected")))
f () { /* Do something. */; }
int i __attribute__ ((visibility ("hidden")));

Возможные значения visibility_type соответствуют настройкам видимости в ELF gABI.

default

Видимость по умолчанию — это нормальный случай для формата файла объекта. Это значение доступно для атрибута видимости, чтобы переопределить другие параметры, которые могут изменить предполагаемую видимость сущностей.

В ELF, видимость по умолчанию означает, что объявление видно другим модулям, а в общих библиотеках означает, что объявленная сущность может быть переопределена.

В Darwin, видимость по умолчанию означает, что объявление видно другим модулям.

Видимость по умолчанию соответствует «внешней связи» в языке.

hidden

Видимость hidden указывает, что объявленная сущность имеет новый тип связи, который мы называем «скрытой связью». Два объявления объекта со скрытой связью относятся к одному объекту, если они находятся в одной общей библиотеке.

internal

Видимость internal похожа на видимость hidden, но с дополнительными семантиками, специфичными для процессора. Если не указано иное psABI, GCC определяет внутреннюю видимость как означающую, что функция никогда не вызывается из другого модуля. Сравните это со скрытыми функциями, которые, хотя их нельзя ссылаться напрямую из других модулей, могут быть обращены косвенно через указатели на функции. Указывая, что функция не может быть вызвана извне модуля, GCC может, например, опустить загрузку регистра PIC, поскольку известно, что вызывающая функция загрузила правильное значение.

protected

Видимость protected подобна видимости по умолчанию, за исключением того, что она указывает, что ссылки внутри определяющего модуля привязываются к определению в этом модуле. То есть, объявленная сущность не может быть переопределена другим модулем.

Все видимости поддерживаются во многих, но не во всех, целевых платформах ELF (поддерживаются, когда ассемблер поддерживает псевдооператор ‘.visibility’). Видимость по умолчанию поддерживается везде. Видимость hidden поддерживается на целевых платформах Darwin.

Атрибут видимости должен применяться только к объявлениям, которые в противном случае имели бы внешнюю связь. Атрибут должен применяться последовательно, так что одна и та же сущность не должна объявляться с разными настройками атрибута.

В C++, атрибут видимости применяется как к типам, так и к функциям и объектам, потому что в C++ типы имеют связь. Класс не должен иметь большей видимости, чем его нестатические типы данных и базовые классы, а члены класса по умолчанию имеют видимость своего класса. Кроме того, объявление без явной видимости ограничено видимостью своего типа.

В C++, вы можете пометить члены-функции и статические члены-переменные класса атрибутом видимости. Это полезно, если вам известно, что определённый метод или статическая переменная члена должны использоваться только из одной общей библиотеки; тогда вы можете пометить его как скрытый, в то время как остальная часть класса имеет видимость по умолчанию. Следует быть осторожным, чтобы не нарушить Правило одной дефиниции; например, обычно не имеет смысла пометить встроенный метод как скрытый, не помечая весь класс как скрытый.

Объявление пространства имен C++ также может иметь атрибут видимости.

namespace nspace1 __attribute__ ((visibility ("protected")))
{ /* Do something. */; }

Этот атрибут применяется только к телу конкретного пространства имен, а не к другим определениям того же пространства имен; он эквивалентен использованию ‘#pragma GCC visibility’ перед и после определения пространства имен (см. Атрибуты видимости).

В C++, если тип шаблона имеет ограниченную видимость, это ограничение неявно распространяется на экземпляризацию шаблона. В противном случае экземпляризации и специализации шаблонов по умолчанию имеют видимость своего шаблона.

Если у шаблона и окружающего класса есть явная видимость, используется видимость из шаблона.

warn_unused_result

Атрибут warn_unused_result вызывает выдачу предупреждения, если вызывающая функция с этим атрибутом не использует её возвращаемое значение. Это полезно для функций, где проверка результата является либо проблемой безопасности, либо всегда ошибкой, например, для realloc.

int fn () __attribute__ ((warn_unused_result));
int foo ()
{
  if (fn () < 0) return -1;
  fn ();
  return 0;
}

приводит к предупреждению на 5-й строке.

weak

Атрибут weak заставляет объявление генерировать слабый символ, а не глобальный. Это в первую очередь полезно при определении функций библиотеки, которые могут быть переопределены в пользовательском коде, хотя оно также может использоваться с объявлениями, не являющимися функциями. Слабые символы поддерживаются для целевых платформ ELF, а также для целевых платформ a.out при использовании GNU ассемблера и линковщика.

weakref
weakref ("target")

Атрибут weakref помечает объявление как слабую ссылку. Без аргументов он должен сопровождаться атрибутом alias, называющим целевой символ. Дополнительно, target может быть задан как аргумент для weakref. В любом случае, weakref неявно помечает объявление как weak. Без target, заданного как аргумент для weakref или alias, weakref эквивалентно weak.

static int x() __attribute__ ((weakref ("y")));
/* is equivalent to... */
static int x() __attribute__ ((weak, weakref, alias ("y")));
/* and to... */
static int x() __attribute__ ((weakref));
static int x() __attribute__ ((alias ("y")));

Слабая ссылка — это псевдоним, для которого само по себе не требуется определение целевого символа. Если целевой символ ссылается только через слабые ссылки, то он становится weak неопределённым символом. Однако, если он ссылается напрямую, то такие сильные ссылки преобладают, и для символа требуется определение, необязательно в той же единице трансляции.

Эффект эквивалентен перемещению всех ссылок на псевдоним в отдельную единицу трансляции, переименованию псевдонима в алиасированный символ, объявлением его как слабого, компиляции двух отдельных единиц трансляции и выполнению линковки с релокируемым выводом (т.е.: ld -r) над ними.

В настоящее время объявление, к которому прикреплён weakref может быть только static.

Далее: Атрибуты функций AArch64, Назад: Атрибуты функций [Содержание][Индекс]

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

Spec-Zone.ru

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