Ответ 1
Как добавить определение функции в файл заголовка?
Это может быть достигнуто тремя возможными способами:
- Отметить функцию
inline
или - Выполнение функции
static
или - Помещение функций в анонимное пространство имен.
Каков правильный способ сделать это?
#1
i.e: Знак функции inline
является правильным способом без нарушения правила Одно определение.
Что не так с двумя другими оценками?
В обоих #2
и #3
каждый модуль перевода будет содержать собственную версию функции, а программа будет содержать несколько разных версий функции, что приведет к увеличению размера сгенерированного двоичного файла.
i.e: Для функции static
fun()
, &fun
будет различной в каждой единицы перевода, а программа будет содержать N
разные версии функции.
Кроме того, если функция содержит статические локальные переменные, тогда будет N
разные статические локальные переменные, по одному для каждого экземпляра функции.
Как первый подход позволяет избежать этой проблемы?
Функция inline
имеет внешнюю связь.
Когда вы отмечаете функцию inline
, функция будет иметь тот же адрес во всех единицах перевода. Кроме того, статические локали и строковые литералы, определенные внутри тела встроенной функции, рассматриваются как один и тот же объект в единицах перевода.
Короче говоря, встроенная функция будет иметь один и тот же адрес во всех единицах перевода.
Какова сделка с определениями функций
static inline
в заголовке?
Ключевое слово static
заставляет функцию иметь внутреннюю связь.
Каждый экземпляр функции, определенный как встроенный, рассматривается как отдельная функция, и каждый экземпляр имеет свою собственную копию статических локалей и строковых литералов. Таким образом, это будет похоже на #2
.
Примечание:
Стандарт требует, чтобы все определения функции inline
выполнялись в пользовательской программе. У вас должно быть точно такое же определение во всех единицах перевода, в которых используется или вызывается функция.
Соответствующие ссылки Standerdese:
Стандарт С++ 03
3.2 Одно правило определения:
Параграф 3:
Каждая программа должна содержать ровно одно определение каждой не-встроенной функции или объекта, которая используется в этой программе; не требуется диагностика. Определение может явно отображаться в программе, оно может быть найдено в стандартной или определяемой пользователем библиотеке или (если необходимо), оно неявно определено (см. 12.1, 12.4 и 12.8). Встроенная функция должна быть определена в каждой единицы перевода, в которой она используется.
7.1.2 Спецификаторы функций
Параграф 4:
Встроенная функция должна быть определена в каждой единицы перевода, в которой она используется, и должна иметь точно такое же определение в каждом случае (3.2). [Примечание: вызов встроенной функции может быть встречен до того, как ее определение появится в блоке перевода. ] Если функция с внешней связью объявлена встроенной в одну единицу перевода, она должна быть объявлена встроенной во все единицы перевода, в которых она отображается; диагностика не требуется. Встроенная функция с внешней связью должна иметь один и тот же адрес во всех единицах перевода. Статическая локальная переменная в anextern встроенной функции всегда относится к одному и тому же объекту. Строковый литерал во внешней встроенной функции - это тот же объект в разных единицах перевода.