Spec-Zone.ru › C

Указатель на встроенную функцию

Объявляет встроенную функцию.

Синтаксис

inline объявление_функции (с C99)

Объяснение

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

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

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

Любая функция с внутренней связью может быть объявлена static inline без каких-либо дополнительных ограничений.

Нестатическая встроенная функция не может определять неконстантную локальную статическую функцию и не может ссылаться на статическую функцию уровня файла.

static int x;
 
inline void f(void)
{
    static int n = 1; // error: non-const static in a non-static inline function
    int k = x; // error: non-static inline function accesses a static variable
}

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

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

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

inline const char *saddr(void) // the inline definition for use in this file
{
    static const char name[] = "saddr";
    return name;
}
 
int compare_name(void)
{
    return saddr() == saddr(); // unspecified behavior, one call could be external
}
 
extern const char *saddr(void); // an external definition is generated, too

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

Ключевые слова

inline

Примечания

Ключевое слово inline было заимствовано из C++, но в C++, если функция объявлена inline, она должна быть объявлена inline в каждом трансляционном блоке, а также каждое определение встроенной функции должно быть точно таким же (в C определения могут отличаться, и в зависимости от различий поведение неопределено). С другой стороны, C++ допускает неконстантные локальные статические функции и все локальные статические функции из различных определений встроенной функции одинаковы в 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); // provides external definition

Файл исходного кода "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);
}

Вывод

10

Ссылки

  • Стандарт C23 (ISO/IEC 9899:2023):
    • 6.7.4 Спецификаторы функций (p: TBD)
  • Стандарт C17 (ISO/IEC 9899:2018):
    • 6.7.4 Спецификаторы функций (p: TBD)
  • Стандарт C11 (ISO/IEC 9899:2011):
    • 6.7.4 Спецификаторы функций (p: 125-127)
  • Стандарт C99 (ISO/IEC 9899:1999):
    • 6.7.4 Спецификаторы функций (p: 112-113)

См. также

Документация C++ по inline указателю

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/c/language/inline

Spec-Zone.ru

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