Namespaces
Variants

inline function specifier

From cppreference.net

Объявляет 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

Примечания

Ключевое слово 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);
}
**Примечание:** Весь представленный код является C++ кодом внутри тегов `
`, поэтому согласно вашим инструкциям он не подлежит переводу. 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 спецификатора