Spec-Zone.ru › GCC 8

6.31.1 Общие атрибуты функций

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

alias ("target")

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

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

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

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

aligned (alignment)

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

Вы не можете использовать этот атрибут для уменьшения выравнивания функции, только для его увеличения. Однако, когда вы явно задаёте выравнивание функции, это переопределяет действие опции -falign-functions (см. Опции оптимизации) для этой функции.

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

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

alloc_align

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

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

Например,

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

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

alloc_size

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

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

Например,

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

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

artificial

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

assume_aligned

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

Например

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.

bnd_instrument

Атрибут bnd_instrument для функций используется для информирования компилятора о том, что функция должна быть проинструментирована при компиляции с опцией -fchkp-instrument-marked-only.

bnd_legacy

Атрибут bnd_legacy для функций используется для информирования компилятора о том, что функция не должна быть проинструментирована при компиляции с опцией -fcheck-pointer-bounds.

cold

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

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

const

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

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

constructor
destructor
constructor (priority)
destructor (priority)

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

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

deprecated
deprecated (msg)

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

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

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

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

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

Если атрибут error или warning используется в объявлении функции, а вызов такой функции не исключается благодаря удалению неиспользуемого кода или другим оптимизациям, диагностируется ошибка или предупреждение (соответственно), содержащее сообщение. Это полезно для проверки во время компиляции, особенно вместе с __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

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

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. На целевых платформах 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 (при этом оставшиеся аргументы функции формата остаются такими же, как и для немодифицированной строки). Например, объявление:

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, но вызовы не могли бы быть проверены без атрибута.

Параметр 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__. См. Встроенная функция так же быстра, как макрос.

В 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, то генерируются профилирующие вызовы функций при входе и выходе из большинства функций, скомпилированных пользователем. Функции с этим атрибутом не проходятся профилированием.

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 (arg-index, …)

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

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

заставляет компилятор проверять, что в вызовах my_memcpy, аргументы dest и src не являются нулевыми. Если компилятор определяет, что в аргументе, помеченном как отличный от нуля, передаётся нулевой указатель, и опция -Wnonnull включена, выводится предупреждение. Компилятор также может выбрать оптимизацию на основе знания того, что определённые аргументы функции никогда не будут нулевыми.

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

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.

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

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

nothrow

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

optimize

Атрибут optimize используется для указания, что функция должна компилироваться с разными параметрами оптимизации, чем указанные в командной строке. Аргументы могут быть числами или строками. Числа предполагаются уровнями оптимизации. Строки, начинающиеся с O, предполагаются параметрами оптимизации, в то время как другие параметры предполагается использовать с префиксом -f. Также можно использовать директиву «#pragma GCC optimize» для установки параметров оптимизации, влияющих на несколько функций. Подробнее о директиве «#pragma GCC 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. Например,

int square (int) __attribute__ ((pure));

указывает, что гипотетическая функция square может быть вызвана меньше раз, чем указано в программе.

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

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

returns_nonnull

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

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

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

returns_twice

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

section ("section-name")

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

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

помещает функцию foobar в сегмент bar.

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

sentinel

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

__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 (options)

Несколько целевых back-end реализуют атрибут target, чтобы указать, что функция должна быть скомпилирована с различными целевыми параметрами, отличными от указанных в командной строке. Это можно использовать, например, для компиляции функций с другой архитектурой набора инструкций (ISA), отличной от стандартной. Также можно использовать псевдоним «#pragma GCC target», чтобы задать более одной функции параметры компиляции для определённых целей. Подробности о псевдониме «#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 visibility.

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

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

default

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

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

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

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

hidden

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

internal

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

protected

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

Все виды видимости поддерживаются во многих, но не во всех, целевых системах ELF (поддерживаются, когда ассемблер поддерживает псевдооператор «.visibility»). Видимость по умолчанию поддерживается везде. Скрытая видимость поддерживается в целевых системах 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 неопределённым символом. Однако, если он прямо ссылается, то такие сильные ссылки имеют приоритет, и определение символа требуется, но не обязательно в том же модуле трансляции.

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

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

Далее: Атрибуты функций AArch64, Назад: Атрибуты функций [Оглавление][Указатель]

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

Spec-Zone.ru

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