Я пытаюсь научиться C. Прочитав какой-то код, я наткнулся на такую строку:
__inline__ void () ...
Что означает __inline__
?. Как помещать это слово перед функцией, делает ее другой?
Я пытаюсь научиться C. Прочитав какой-то код, я наткнулся на такую строку:
__inline__ void () ...
Что означает __inline__
?. Как помещать это слово перед функцией, делает ее другой?
__inline__
является нестандартным расширением. Как правило, он сообщает компилятору: "встроить эту функцию", но, будучи нестандартным расширением, мы не можем сказать с уверенностью, если мы не знаем, какой компилятор это включен.
В строку "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.
Inline - это предложение компилятору встроить функцию - вместо генерации блока кода для функции и инструкций call
, где бы он ни использовался, он эффективно вырезает и сгенерирует сгенерированный код везде, где вызывается эта функция.
Как правило, это только предложение - хотя оно может повысить производительность, если оно вызвано в жестком цикле, оно обычно увеличивает использование памяти, что может иметь в целом отрицательные эффекты производительности. Компилятор сам решит, следует ли встроить функцию или нет - может потребоваться "программист предлагает включить это", но (в большинстве компиляторов) просто объявление функции как встроенного не гарантирует, что это будет.
В информатика, встроенная функция - это язык программирования, используемый для описания compiler, он должен выполнить встроенное расширение для определенной функции. Другими словами, компилятор будет вставлять полный кусок функции в любое место в коде, где эта функция используется.
Если вы пишете заголовочный файл, который должен быть включен в программы ISO C89, напишите
__inline__
вместоinline
. См. Альтернативные ключевые слова.
Объявление __inline__
сообщает компилятору, что везде, где функция будет вызываться для "встроенной" функции. Inlineing аналогичен использованию макроса - код будет расширен, как если бы вы все правильно написали, где вы вызвали функцию.
Подробнее см. GNU docs.
в основном, это подсказка для компилятора; это предложение о том, что там, где используется эта функция, возможно было бы непосредственно вставить код.
идея состоит в том, что выполнение этого может быть более эффективным, поскольку оно позволяет избежать накладных расходов на вызов функции; но, в конечном счете, компилятор использует комбинацию размера кода, указанных опций оптимизации и немного вуду, чтобы решить, действительно ли соблюдать этот намек.
бит вуду - самая запутанная часть.:) не обязательно полагаться на __inline__
(или более стандартный встроенный) на работу; оптимизируйте свои алгоритмы или переконфигурируйте свой код, если вам действительно нужна скорость.