2011-05-11 6 views
57

Почему я должен сделать что-то вроде этого:встроенная функция C++?

inline double square (double x) { return x*x;} 

вместо

double square (double x) { return x*x;} 

Есть ли разница?

+0

возможно дубликат [функций Инлайн против Препроцессор макросов] (http://stackoverflow.com/questions/1137575/inline-functions-vs-preprocessor-macros) –

+0

На самом деле есть много простофиль и около-dupes: http://stackoverflow.com/search?q=c%2B%2B+inline. Некоторые ответы лучше других, некоторые из них ошибочно утверждают, что ключевое слово 'inline' заставляет функцию быть встроенным на всех сайтах и ​​так далее. Возможно, это не самый близкий друг. –

ответ

73

Первый (с использованием inline) позволяет поместить эту функцию в файл заголовка, где он может быть включен в несколько исходных файлов. Использование inline делает идентификатор в файловом пространстве, как объявление static. Без использования inline вы получите ошибку компоновщика с несколькими символами.

Конечно, это в дополнение к подсказке компилятору о том, что функция должна быть скомпилирована inline туда, где она используется (без использования служебных вызовов функции). Компилятор не обязан действовать по подсказке inline.

+1

Я думал, что цель inline заключается в том, чтобы компилятор «расширил» содержимое функции, где он вызывается, поэтому не будет vtable-поиска (или перехода команды к функции на уровне ЦП). –

+0

Является ли ваш первый пункт [полезным] побочным эффектом по назначению? –

+0

@Ian Fleeton: Это действительно побочный эффект; если у встроенного идентификатора не было области файла, тогда было бы невозможно установить определение встроенной функции в файл заголовка. –

20

На современном компиляторе, вероятно, не так много различий. Он может быть встроен без inline, и он может не быть встроенным сinline.

+0

Имеет смысл, я пошел от справки и 10-летнего опыта. –

27

Да, есть разница. https://isocpp.org/wiki/faq/inline-functions.

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

void myfunc() { 
    square(2); 
} 

идентичен

void myfunc() { 
    2 * 2; 
} 

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

Теперь, если вы повышаете уровень оптимизации, компилятор будет принимать решения, такие как разворачивание циклов или функции инкрустации. Компилятор по-прежнему может игнорировать встроенный оператор.

+2

Я думаю, что с помощью gcc вы можете использовать флаг компиляции '-Winline' для предупреждения, когда функция не будет встраиваться. И вы можете совместить это с «-Werror», если вы массовый человек. – patmanpato

2

Встроенная функция, если компилятор соответствует, будет включать встроенную функцию в код, в котором она была вызвана, как если бы не вызывалась функция (как если бы вы поместили логику в вызывающую функцию) и избегаете вызова функции накладные расходы.

+6

Компилятор не должен включать функцию, если она не хочет, даже если указано ключевое слово inline. – Marlon

+1

@ Алекс Марлон не сказал, что компилятор ** не будет ** встроить функцию, просто потому, что она ** не должна **. Это очень разные вещи. – anthropomorphic

2

inline хорошо работает с концепцией процедурной абстракции:

inline double square (double x) { return x*x;} 

int squareTwice(double x) { 
    double first = square(x); 
    double second = square(x); 
    return first * second; 
} 

выше принципиально аналогично следующему:

int squareTwice(double x) { 
    double first = x*x; 
    double second = x*x; 
    return first * second; 
} 

Это происходит потому, что когда компилятор рядный расширяет функции вызов, код функции вставляется в поток кода вызывающего абонента; поэтому, может быть, проще подвергнуть процедуре абстрагирование второго примера с первым примером.

Процедурная абстракция позволяет разбить рутину на более мелкие подпрограммы, которые намного легче читать (хотя это может быть выбор стиля).

5

Материал из Википедии: Встроенная функция - это функция, от которой компилятор запросил выполнить встроенное расширение. Другими словами, программист запросил, чтобы компилятор вставлял полный кусок функции в каждое место, вызываемое функцией, а не генерировал код для вызова функции в одном месте, где он определен. Составители не обязаны соблюдать этот запрос.

http://en.wikipedia.org/wiki/Inline_function

Смежные вопросы