inline function specifier
Объявляет inline function .
Содержание |
Синтаксис
| inline объявление_функции | (начиная с C99) | ||||||||
Объяснение
Назначение спецификатора
inline
заключается в том, чтобы служить подсказкой для компилятора выполнять оптимизации, такие как
подстановка функций
, которые обычно требуют, чтобы определение функции было видимо в месте вызова. Компиляторы могут (и обычно так и делают) игнорировать наличие или отсутствие спецификатора
inline
для целей оптимизации.
Если компилятор выполняет подстановку функций, он заменяет вызов этой функции её телом, избегая накладных расходов на вызов функции (размещение данных в стеке и извлечение результата), что может привести к увеличению исполняемого файла, поскольку код функции приходится повторять несколько раз. Результат похож на макросы-функции , за исключением того, что идентификаторы и макросы, используемые в функции, ссылаются на определения, видимые в точке определения, а не в точке вызова.
Независимо от того, происходит ли подстановка, гарантированы следующие семантика inline-функций:
Любая функция с внутренней линковкой может быть объявлена
static inline
без каких-либо дополнительных ограничений.
Нестатическая встроенная функция не может определять неконстантную статическую переменную в области видимости функции и не может ссылаться на статическую переменную в области видимости файла.
static int x; inline void f(void) { static int n = 1; // ошибка: неконстантная статическая переменная в нестатической inline-функции int k = x; // ошибка: нестатическая inline-функция обращается к статической переменной }
Если нестатическая функция объявлена
inline
, то она должна быть определена в той же единице трансляции. Встроенное определение, которое не использует
extern
, не является видимым извне и не препятствует другим единицам трансляции определять ту же функцию. Это делает ключевое слово
inline
альтернативой
static
для определения функций внутри заголовочных файлов, которые могут быть включены в несколько единиц трансляции одной программы.
Если функция объявлена
inline
в некоторых единицах трансляции, она не обязана быть объявленной
inline
везде: не более чем в одной единице трансляции может также предоставляться обычная, не-inline не-статическая функция, или функция, объявленная
extern inline
. Эта единица трансляции называется предоставляющей
внешнее определение
. Во избежание неопределённого поведения, одно внешнее определение должно существовать в программе, если имя функции со внешней компоновкой используется в выражении, см.
правило одного определения
.
Адрес встроенной функции с внешней линковкой всегда является адресом внешнего определения, но когда этот адрес используется для вызова функции, не определено, будет вызвано встроенное определение (если оно присутствует в единице трансляции) или внешнее определение . Статические объекты, определённые во встроенном определении, отличаются от статических объектов, определённых во внешнем определении:
inline const char *saddr(void) // встроенное определение для использования в этом файле { static const char name[] = "saddr"; return name; } int compare_name(void) { return saddr() == saddr(); // неопределённое поведение, один вызов может быть внешним } extern const char *saddr(void); // также генерируется внешнее определение
Программа на C не должна зависеть от того, вызывается ли встроенная версия или внешняя версия функции, иначе поведение не определено.
Ключевые слова
Примечания
Ключевое слово
inline
было заимствовано из C++, однако в C++, если функция объявлена как
inline
, она должна быть объявлена
inline
в каждой единице трансляции, и каждое определение inline-функции должно быть идентичным (в C определения могут различаться, и в зависимости от различий поведение является неопределённым). С другой стороны, C++ допускает неконстантные статические локальные переменные функций, и все статические локальные переменные из разных определений inline-функции в C++ являются одними и теми же, тогда как в C они различны.
Пример
Заголовочный файл "test.h"
#ifndef TEST_H_INCLUDED #define TEST_H_INCLUDED inline int sum(int a, int b) { return a + b; } #endif
Исходный файл "sum.c"
#include "test.h" extern inline int sum(int a, int b); // предоставляет внешнее определение
Исходный файл "test1.c"
#include <stdio.h> #include "test.h" extern int f(void); int main(void) { printf("%d\n", sum(1, 2) + f()); }
Исходный файл "test2.c"
#include "test.h" int f(void) { return sum(3, 4); }
`, поэтому согласно вашим инструкциям он не подлежит переводу. HTML структура и форматирование полностью сохранены.
Вывод
10
Ссылки
- Стандарт C23 (ISO/IEC 9899:2024):
-
- 6.7.4 Спецификаторы функций (стр.: TBD)
- Стандарт C17 (ISO/IEC 9899:2018):
-
- 6.7.4 Спецификаторы функций (стр.: TBD)
- Стандарт C11 (ISO/IEC 9899:2011):
-
- 6.7.4 Спецификаторы функций (стр: 125-127)
- Стандарт C99 (ISO/IEC 9899:1999):
-
- 6.7.4 Спецификаторы функций (стр. 112-113)
Смотрите также
|
Документация C++
для
inline
спецификатора
|