Ответ 1
__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.