Ответ 1
У вас это почти правильно. Вы действительно имеете это назад; для встроенных функций вы должны поместить определение inline
в заголовочный файл и объявление extern
в файл C.
// mymath.h
inline float clampf( float v, float min, float max )
{
if( v < min ) v = min;
if( v > max ) v = max;
return v;
}
// mymath.c
#include "mymath.h"
extern float clampf( float v, float min, float max );
Вы должны поместить определение (полное тело) в заголовочный файл, это позволит любому файлу, который включает файл заголовка, в возможности использовать встроенное определение, если компилятор решит это сделать.
Вы должны поместить объявление extern
(прототип) в исходный файл, чтобы сообщить компилятору испустить внешнюю версию функции в библиотеке. Это обеспечивает одно место в вашей библиотеке для не-встроенной версии, поэтому компилятор может выбирать между встраиванием функции или использованием общей версии.
Обратите внимание, что это может плохо работать с компилятором MSVC, который в целом имеет очень низкую поддержку для C (и имеет почти нулевую поддержку для C99). Для GCC вам нужно будет включить поддержку C99 для старых версий. Современные компиляторы C поддерживают этот синтаксис по умолчанию.
Альтернатива:
Вы можете изменить заголовок, чтобы иметь версию static inline
,
// mymath.h
static inline float clampf(float v, float min, float max)
{
...
}
Однако это не обеспечивает не встроенную версию функции, поэтому компилятор может быть вынужден создать копию этой функции для каждой единицы перевода.
Примечания:
-
Правила встраивания C99 не совсем интуитивно понятны. В статье "Встроенные функции в C" (mirror) подробно описывается. В частности, пропустите снизу и посмотрите "Стратегии использования встроенных функций". Я предпочитаю метод # 3, так как GCC уже некоторое время отказывается от метода C99.
-
Технически вам не нужно помещать
extern
в объявление функции (или определение), так какextern
является значением по умолчанию. Я положил его туда для акцента.