Spec-Zone.ru › GCC 14

6.45 Встроенная функция так же быстра, как макрос

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

GCC реализует три различные семантики объявления встроенной функции. Одна доступна с -std=gnu89 или -fgnu89-inline или когда атрибут gnu_inline присутствует во всех объявлениях встроенных функций, другая — когда используется -std=c99, -std=gnu99 или параметр более поздней версии C (без -fgnu89-inline), и третья используется при компиляции C++.

Чтобы объявить функцию встроенной, используйте ключевое слово inline в её объявлении, например так:

static inline int
inc (int *a)
{
  return (*a)++;
}

Если вы пишете заголовочный файл для включения в программы ISO C90, запишите __inline__ вместо inline. См. Альтернативные ключевые слова.

Три типа встраивания ведут себя аналогично в двух важных случаях: когда ключевое слово inline используется для функции static, как в примере выше, и когда функция сначала объявляется без использования ключевого слова inline и затем определяется с inline, как в этом примере:

extern int inc (int *a);
inline int
inc (int *a)
{
  return (*a)++;
}

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

Когда функция является одновременно встроенной и static, если все вызовы функции интегрированы в вызывающую функцию, и адрес функции никогда не используется, то собственный код ассемблера функции никогда не используется. В этом случае GCC фактически не выводит код ассемблера для функции, если вы не укажете параметр -fkeep-inline-functions. Если имеется неинтегрированный вызов, то функция компилируется в код ассемблера обычным образом. Функция также должна компилироваться обычным образом, если программа ссылается на её адрес, потому что это нельзя встроить.

Обратите внимание, что определённые способы использования в определении функции могут сделать её непригодной для встроенной подстановки. К ним относятся: функции с переменным числом аргументов, использование alloca, использование вычисленных переходов (см. Метки как значения), использование нелокальных переходов, использование вложенных функций, использование setjmp, использование __builtin_longjmp и использование __builtin_return или __builtin_apply_args. Использование -Winline предупреждает, когда функция, помеченная как inline, не может быть подставлена, и указывает причину неудачи.

В соответствии с требованиями ISO C++, GCC рассматривает член-функции, определённые в теле класса, как помеченные как встроенные, даже если они не явно объявлены с ключевым словом inline. Вы можете переопределить это с помощью -fno-default-inline; см. Параметры, контролирующие диалект C++.

GCC не встраивает никакие функции при отсутствии оптимизации, если вы не укажете атрибут «always_inline» для функции, например так:

/* Prototype.  */
inline void foo (const char) __attribute__((always_inline));

Остальная часть этого раздела относится к встраиванию GNU C90.

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

Если вы укажете как inline, так и extern в определении функции, то определение используется только для встраивания. В любом случае функция не компилируется самостоятельно, даже если вы явно ссылаетесь на её адрес. Такой адрес становится внешней ссылкой, как если бы вы только объявили функцию, но не определили её.

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

© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-13.3.0/gcc/Inline.html

Spec-Zone.ru

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