2010-11-24 2 views
3

В чем разница между этими 2 определениями ниже:Что это за линия?

#define DEFINE_BIT_MASK_ENUM_AND_OR(Type) \ 
inline Type EnumBitMaskOr(Type lhs, Type rhs) { return lhs | rhs; } \ 

#define DEFINE_BIT_MASK_ENUM_AND_OR(Type) \ 
Type EnumBitMaskOr(Type lhs, Type rhs) { return lhs | rhs; } \ 

ответ

2

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

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

+0

`функция должна быть встроена, если возможно`, вы упомянули« если возможно », есть ли случай, когда встроенный невозможно? – wp2 2010-11-24 11:02:40

+0

@ wp2 да, например, если это рекурсивный или слишком длинный – 2010-11-24 11:04:09

0

Разница заключается в том, что в первом случае не происходит вызова функции. Функция «inlined», что означает, что вызов заменяется телом метода. Это помогает оптимизировать выполнение, поскольку контекст не должен быть сохранен перед вызовом и впоследствии восстановлен.

0

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

0

Ключевое слово "inline" используется для указания компилятору, что вы хотите, чтобы он выполнял встроенное расширение функции или, другими словами, расширил функцию вместо вызова.

Несколько пунктов, чтобы сделать

  1. Причина это обычно делается, чтобы сохранить накладные расходы на вызов другой функции
  2. «инлайн» ключевое слово только запрос на компилятор и компилятор может решить стоит ли его почитать или нет
  3. Вложение может иметь непреднамеренные последствия, поэтому следует использовать с осторожностью
  4. Компилятор сегодня обычно лучше подходит для определения того, какие функции должны быть встроены для вас, и будет делать это автоматически, если соответствующий аргумент s предоставляется компилятор
2

Поскольку на мой вкус всех ответов, даже принятые один, получить главный аспект inline неправильно и, в частности, в том, что это означает для использования в макросах, я стараюсь еще один.

Ключевое слово inline определяет, приведет ли определение функции (не объявление) к генерации функции в текущем блоке компиляции. Есть в основном 3 случая:

  • Если вы просто поставить «простое» определение функция должна быть сгенерирована и внешним символом для этой функции вставления.
  • Для определения inline функция может быть сгенерирована и если это так, может или не может вставить внешний символ к объекту.
  • Для определения static функция может быть сгенерирована (как правило, если она используется), но имя никогда не будет внешним символом.

Для первого, если два блока компиляции определяют одну и ту же функцию, при связывании двух файлов объектов в одном исполняемом файле возникнет ошибка.

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

Что касается макросов, которые представлены в вопросе, это имеет важное функциональное различие. Первый, inline, может быть расширен где угодно, особенно в файле заголовка, не вызывая конфликтов. Второй может использоваться только в файле .c, и, кроме того, не должно быть двух таких .c, если они должны быть в одном исполняемом файле.


Edit: w.r.t на комментарий Чарльза. inline Функции могут также быть и внешними символами. Правила для этого немного сложны, см. Соответствующий пункт 6.7.4 с C99 ниже. В основном есть три случая, которые будут работать, если у вас есть несколько единиц перевода, которые будут связаны вместе

  1. объявить и определить функцию extern inline в файл .h и декларировать это снова просто inline без extern точно один .c файл.
  2. объявить и определить функцию в формате .h и обновить ее без inline в одном формате .c. На самом деле это похоже на создание шаблонных функций в C++.
  3. объявить и определить функцию inline в .h файле и обновить его extern inline в одном файле .c.

Перед версией 4.3 у gcc была другая модель для такого типа экземпляров функций inline, которые несовместимы с этой нормативной. See also this page for a good read on this subject.

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

0

Я отметил в комментарии к unwind's answer, что вы хотели знать следующее:

Если функция не может быть встраиваемыми, и был отмечен, так что вы получите предупреждение, если вы передаете -Winline в НКУ.

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