Допустим, у нас есть короткая функция:
Код:
inline int squared(const int argument)
{
return argument * argument;
}
Следуя рекомендациям, ставим ей спецификатор inline (некоторые пишут, что она итак заинлайнится компилятором, так как очень маленькая, но это сути не меняет). Тогда, как везде написано про inline, компилятор подставит код функции в место её вызова, а не сделает функцию. То есть, казалось бы, код:
Код:
// ...
int x = squared(y);
// ...
будет полностью эквивалентен коду
Код:
// ...
int x = y * y;
// ...
Рассмотрим теперь ситуацию, когда код вызова чуток другой, а именно - аргументом будет не переменная, а возвращённое из другой функции значение:
Код:
// ...
int x = squared(my_function(y));
// ...
Казалось бы, этот код, по ранее описанной логике, должен развернуться в
Код:
// ...
int x = my_function(y) * my_function(y);
// ...
, что приведёт к двойному вызову my_function(y), если последняя функция вычисляется долго, то мы сразу схватим падение производительности. Если бы функция не заинлайнилась, то сначала бы вызвалась my_function(y), и её вычисленное значение было бы подставлено в качестве аргумента функции squared(...), то есть код был бы эквивалентен чему-то типа:
Код:
// ...
int arg = my_function(y);
int x = arg * arg;
// ...
Если inline работает именно так, то это очень плохо, так как получается, что результат компиляции зависит от того, будет ли функция заинлайнена, или нет, а не от того, что написано в коде. Плюс в описанном примере (а подобных можно сделать немало) такой инлайнинг напрочь уничтожает преимущества от использования функции (и вообще, в этом примере тогда инлайнинг нужно бы как-то запретить).
Вопрос - правильно ли я понял, что inline функции работает так, как описано выше? У них действительно возникает такой косяк (то есть, по сути описанная функция squared(...) ничем не отличается от макроса
Код:
#define squared(A) (A) * (A)
)? Или же я неправ, и при инлайнинге каким-то образом всё же будет вычислено значение аргумента, и функция будет "будто бы вызвана" от вычисленного значения, а не просто будет подставлено выражение?
Прошу прощения, если этот вопрос легко гуглится, у меня не получилось - про inline много пишут, но конкретно по этому вопросу не нашёл, видимо те, кого волнуют такие "оптимизации", итак уже отлично понимают работу inline функций (я, кстати, подобные короткие функции ровно для этого и пишу - чтобы ликвидировать повторные бестолковые вычисления).
Кстати, возможно этот вопрос можно уяснить через тестовый проект, который потом дизассемблером прогнать, но я не умею этого делать, да и вообще с ассемблером пока совсем плох, поэтому спрашиваю - может есть люди, которые точно знают ответ на этот вопрос
.