небольшие функции, определенные в заголовочных файлах: встроенные или статические? - PullRequest
20 голосов
/ 24 февраля 2012

У меня есть несколько небольших функций, которые определены в файле .h.Это небольшой проект (сейчас), и я хочу избежать боли, связанной с разделением объявлений и определений, потому что они все время меняются.Чтобы избежать многократных символов, я могу иметь их либо static, либо inline.Что следует отдавать предпочтение и почему?

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

Ответы [ 3 ]

25 голосов
/ 24 февраля 2012

Я бы использовал static inline, но static также сработал бы.

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

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

Однако определения static имеют внутреннюю связь, поэтому между static и static inline нет большой разницы;Я предпочитаю static inline для определений функций в заголовочных файлах по чисто стилистическим причинам (практическое правило: заголовочные файлы должны содержать только extern объявлений, static const определений переменных и static inline определений функций).

inline без static или extern приводит к встроенному определению , которое стандартное состояние (C99 6.7.4, §6)

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

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

Дополнительную информацию о тонкостях встроенной семантики C99 можно найти в этом ответе , на домашней странице Clang и Обоснование C99 (PDF) .

Имейте в виду, что GCC будет использовать семантику C99, только если присутствует -std=c99 или -std=gnu99 ...

3 голосов
/ 24 февраля 2012

Поскольку речь идет о C (не C ++), inline означает, что

  1. Вы хотите ", который вызывает функцию как можно быстрее" (ISO9899-1999, 6,7,4 (5)).В том же параграфе также указывается, что он определяется реализацией, в какой степени это предложение является эффективным.Другими словами, он не имеет большого значения и не подразумевает какого-либо встраивания вообще (на самом деле, без встраивания вполне может быть быстрее из-за эффектов кэша команд).
  2. есть некоторые ограничения и особые случаи в комбинациис extern (ISO9899-1999, 6.7.4 (6), например, функция inline с внешней связью должна быть определена в том же модуле компиляции, а встроенное определение позволяет externопределение в другом месте без ошибки (что не обязательно является хорошей вещью, поскольку эти две функции не обязательно должны быть функционально эквивалентными, и не определено, какую из них использует компилятор в любое время!).

Компоновщикзначения, данные Heptic, требуются для C ++, но не требуются для C (насколько я могу судить). Они обязательно требуются для "должны иметь одинаковый адрес во всех единицах перевода" в ISO14882,7.1.2 (4). Мне неизвестно о каком-либо подобном предложении в C99.
Однако, поскольку совершенно разные языки C иC ++ обычно проходит через один и тот же компилятор и компоновщик C / C ++, в любом случае он, вероятно, работает одинаково для C.

Итак ... как ответить на ваш вопрос?Используйте inline, когда вы чувствуете, что это достаточно.Знайте о возможных ловушках extern.В противном случае, оставьте это в покое и доверьтесь компилятору сделать все правильно.

0 голосов
/ 24 февраля 2012

Я думаю, static inline - это путь для функций, которые вы хотите встроить, и только static для тех, кто вам не нужен.

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

...