Есть ли способ встроить только некоторые выборочные вызовы функции, не все из них? - PullRequest
3 голосов
/ 30 сентября 2010

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

Ответы [ 5 ]

5 голосов
/ 30 сентября 2010

обратите внимание, что если вы используете встроенное ключевое слово, это только подсказка для компилятора. Вы не можете реально контролировать то, что встроен компилятором, а что нет.

Если ваш компилятор будет следовать вашим советам, вы можете сделать:

inline void doItInline() {...}
void doItNonInline() {doItInline();}

Теперь вы можете вызывать метод inline'd или нет.

2 голосов
/ 30 сентября 2010

Во-первых, некоторый фон для вставки.

Существует несколько этапов, когда может происходить вставка (например):

  • во время компиляции, компилятор может решить (или нет)для встроенного вызова.
  • во время соединения, если LTO включен, компоновщик может решить встроить некоторые вызовы.
  • во время загрузки для языков, которые его поддерживают.

Все они имеют общую точку: они выборочно встроены, т. Е. Стоит ли это в точке вызова.

В C ++ вы можете намекнуть компилятору, что функция может быть полезна для встраиванияиспользуя inline, но он все равно выполнит анализ производительности со своей собственной эвристикой.Основное использование заключается в том, что свободные функции, объявленные как встроенные, не приводят к сбоям связи из-за дублирования символов.

MSVC также поддерживает __forceinline, что приводит к действию inline ..., если это невозможно (виртуальный вызов, указатель функции, / O0, ...)

Поэтому: насколько я знаю, на самом деле невозможно форсировать / предотвратить встраивание.LTO даже позволяет (в некоторых случаях) использовать виртуальные методы (что требует анализа всей программы, поэтому подходит только на этапе exec).

2 голосов
/ 30 сентября 2010

Вы можете попытаться заставить его наоборот.

даже если вы попросите компилятор встроить, он не сможет этого сделать, если определение не доступно в текущем модуле компиляции и ему нужно создать вызов.

если вы убедитесь, что определение доступно, компилятор МОЖЕТ включить его.

0 голосов
/ 30 сентября 2010

Решением будет использование макроса:

#define myfunc_inlined(a,b) (a + b)

int myfunc(int a, int b)
{
    return myfunc_inlined(a,b);
}

int main()
{
    int i = myfunc_inlined(1, 3); #macro call
    int j = myfunc(1, 3);         #standard call
}
0 голосов
/ 30 сентября 2010

переносить встроенную версию с не встроенной определенной версией?

inline void f_inline () {}

void f_not_inline () {f_inline ();}
...