Поскольку на мой вкус всех ответов, даже принятые один, получить главный аспект inline
неправильно и, в частности, в том, что это означает для использования в макросах, я стараюсь еще один.
Ключевое слово inline
определяет, приведет ли определение функции (не объявление) к генерации функции в текущем блоке компиляции. Есть в основном 3 случая:
- Если вы просто поставить «простое» определение функция должна быть сгенерирована и внешним символом для этой функции вставления.
- Для определения
inline
функция может быть сгенерирована и если это так, может или не может вставить внешний символ к объекту.
- Для определения
static
функция может быть сгенерирована (как правило, если она используется), но имя никогда не будет внешним символом.
Для первого, если два блока компиляции определяют одну и ту же функцию, при связывании двух файлов объектов в одном исполняемом файле возникнет ошибка.
Для более поздних, если два блока компиляции определяют одну и ту же функцию, оба объектных файла будут содержать копии функции, которые не будут объединены при их соединении.
Что касается макросов, которые представлены в вопросе, это имеет важное функциональное различие. Первый, inline
, может быть расширен где угодно, особенно в файле заголовка, не вызывая конфликтов. Второй может использоваться только в файле .c, и, кроме того, не должно быть двух таких .c, если они должны быть в одном исполняемом файле.
Edit: w.r.t на комментарий Чарльза. inline
Функции могут также быть и внешними символами. Правила для этого немного сложны, см. Соответствующий пункт 6.7.4 с C99 ниже. В основном есть три случая, которые будут работать, если у вас есть несколько единиц перевода, которые будут связаны вместе
- объявить и определить функцию
extern inline
в файл .h и декларировать это снова просто inline
без extern
точно один .c файл.
- объявить и определить функцию в формате .h и обновить ее без
inline
в одном формате .c. На самом деле это похоже на создание шаблонных функций в C++.
- объявить и определить функцию
inline
в .h файле и обновить его extern inline
в одном файле .c.
Перед версией 4.3 у gcc была другая модель для такого типа экземпляров функций inline
, которые несовместимы с этой нормативной. See also this page for a good read on this subject.
Любая функция с внутренней связью может быть встроенная функция. Для функции с внешней связью применяются следующие ограничения : Если функция , заявленная с помощью встроенной функции , то она также должна быть , определенной в той же единице перевода. Если все деклараций области файла для функции в ЕПЕ включать встроенные функции спецификатора без экстерна, то определение в , что единица перевода является встроенным определения. В встроенном определении не предоставляет внешнего определения для функции и не запрещает внешнее определение в другом блоке перевода . Встроенное определение предоставляет альтернативу внешнему определению , которое переводчик может использовать для осуществления любого вызова функции в той же самой единице перевода.Это не указано, использует ли вызов функцию встроенное определение или внешнее определение .
`функция должна быть встроена, если возможно`, вы упомянули« если возможно », есть ли случай, когда встроенный невозможно? – wp2 2010-11-24 11:02:40
@ wp2 да, например, если это рекурсивный или слишком длинный – 2010-11-24 11:04:09