inline
делает две вещи:
- дает вам освобождение от "правила одного определения" (см. Ниже). Это всегда применяется.
- Дает компилятору подсказку, чтобы избежать вызова функции. Компилятор может игнорировать это.
# 1 Может быть очень полезным (например, поместить определение в заголовок, если оно короткое), даже если # 2 отключено.
На практике компиляторы часто лучше разбираются в том, что делать самим (особенно если доступна оптимизация по профилю).
[РЕДАКТИРОВАТЬ: Полный список литературы и соответствующий текст]
Обе вышеуказанные точки следуют из стандарта ISO / ANSI (ISO / IEC 9899: 1999 (E), широко известного как «C99»).
В §6.9 «Внешнее определение», параграф 5:
Внешнее определение - это внешнее объявление, которое также является определением функции (кроме встроенного определения) или объекта. Если идентификатор, объявленный с внешней связью, используется в выражении (кроме как как часть операнда оператора sizeof, результатом которого является целочисленная константа), где-то во всей программе должно быть ровно одно внешнее определение для идентификатора; в противном случае их должно быть не больше одного.
Хотя эквивалентное определение в C ++ явно названо правилом единого определения (ODR), оно служит той же цели. Внешние элементы (т. Е. Не «статические» и, следовательно, локальные по отношению к одному модулю трансляции - как правило, к одному исходному файлу) могут быть определены только один раз , если не является функцией и inline.
В §6.7.4, «Спецификаторы функций», определено ключевое слово inline:
Создание функции как встроенной функции предполагает, что вызовы этой функции
как можно быстрее. [118] Степень эффективности таких предложений
реализации.
И сноска (ненормативная), но дает пояснения:
Используя, например, альтернативу обычному механизму вызова функции, например, "inline substitution". Встроенная замена не является текстовой заменой и не создает новую функцию. Поэтому, например, при расширении макроса, используемого в теле функции, используется определение, которое оно имело в точке появления тела функции, а не там, где вызывается функция; и идентификаторы ссылаются на объявления в области видимости тела. Аналогично, функция имеет один адрес, независимо от количества встроенных определений, которые встречаются в дополнение к внешнему определению.
Резюме: большинство пользователей C и C ++ ожидают от inline не того, что они получают. Его очевидная основная цель, чтобы избежать функциональных вызовов, полностью необязательна. Но для обеспечения возможности отдельной компиляции требуется ослабление одного определения.
(все выделено в кавычках из стандарта.)
РЕДАКТИРОВАТЬ 2: Несколько примечаний:
- Существуют различные ограничения для внешних встроенных функций. У вас не может быть статической переменной в функции, и вы не можете ссылаться на статические объекты / функции области видимости TU.
- Только что видел это на VC ++ " оптимизация всей программы ", который является примером компилятора, делающего свою собственную встроенную вещь, а не автора.