__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.