Что означает __inline__? - PullRequest
       11

Что означает __inline__?

32 голосов
/ 17 января 2010

Я пытаюсь выучить C. Читая какой-то код, я натолкнулся на такую ​​строку:

__inline__ void () ...

Что означает __inline__? Как размещение этого слова перед функцией делает его другим?

Ответы [ 5 ]

39 голосов
/ 17 января 2010

__inline__ является нестандартным расширением. Как правило, он говорит компилятору: «встроить эту функцию», но, будучи нестандартным расширением, мы не можем с уверенностью сказать, если не знаем, какой это компилятор.

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

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

int min(int x, int y)
{
    return (x < y) ? x : y;
}

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

int a = /* some calculation */;
int b = /* some other calculation */;

int minCalc = min(a, b);

И компилятор вставил эту функцию в код:

int a = /* some calculation */;
int b = /* some other calculation */;

int minCalc = (a < b) ? a : b;

Что снимает накладные расходы при вызове функции. Отсюда можно сделать еще больше оптимизаций, поскольку компилятор начинает работать непосредственно с кодом, который обычно был бы скрыт за вызовом функции. Как вы можете видеть, если у меня есть большая функция, и я заставляю компилятор вставлять ее повсюду, размер кода может вырасти очень большой и очень быстрый, и фактически будет препятствовать скорости выполнения.

Существует стандартное ключевое слово inline, которое использовалось для указания компилятору, что функция должна быть встроенной, но в настоящее время большинство компиляторов даже не признают ее как подсказку для встроенной функции.

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

7 голосов
/ 17 января 2010

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

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

4 голосов
/ 17 января 2010

Википедия / Встроенная функция

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

Руководство GCC § 5.36

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

1 голос
/ 17 января 2010

Объявление __inline__ сообщает компилятору, что везде, где функция будет вызываться, чтобы "встроить" функцию вместо этого.Встраивание аналогично использованию макроса - код будет развернут так, как если бы вы написали все правильно там, где вы вызывали функцию.

См. Документы GNU для получения дополнительной информации.

0 голосов
/ 17 января 2010

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

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

бит вуду - самая запутанная часть. :) не обязательно полагаться на __inline__ (или более стандартный встроенный) для работы; оптимизируйте свои алгоритмы или реорганизуйте код, если вы действительно заботитесь о скорости.

...