Подтвердить что ты не робот

Небольшие функции, определенные в файлах заголовков: встроенные или статические?

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

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

4b9b3361

Ответ 1

Я бы использовал 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...

Ответ 2

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

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

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

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

Ответ 3

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

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