Cómo correctamente en línea para las bibliotecas estáticas

Estoy reescribiendo una pequeña biblioteca de matemáticas en C que terminará como una biblioteca estática para el usuario y me gustaría beneficiarme de la incorporación de la interfaz de vector matemática.

Tengo los siguientes

[mymath.h]

... ... extern float clampf( float v, float min, float max ); ... ... 

[mymath.c]

 inline float clampf( float v, float min, float max ) { if( v  max ) v = max; return v; } 

Como mi biblioteca será estática y solo proporcionaré el .h (y el .lib ) al usuario, ¿la función clampf estará clampf en su progtwig cuando se compile?

¿Estoy haciendo lo correcto pero declarando la función extern en .h e inline en .c ?

Lo tienes casi correcto. Realmente lo tienes al revés; para las funciones en línea, debe colocar la definición en inline en el archivo de encabezado y la statement extern en el archivo 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 ); 

Debe colocar la definición (cuerpo completo) en el archivo de encabezado, esto permitirá que cualquier archivo que incluya el archivo de encabezado pueda usar la definición en línea si el comstackdor decide hacerlo.

extern colocar la statement extern (prototipo) en el archivo fuente para decirle al comstackdor que emita una versión externa de la función en la biblioteca. Esto proporciona un lugar en su biblioteca para la versión no en línea, por lo que el comstackdor puede elegir entre alinear la función o usar la versión común.

Tenga en cuenta que esto puede no funcionar bien con el comstackdor MSVC, que tiene un soporte muy pobre en general para C (y tiene casi cero soporte para C99). Para GCC, tendrá que habilitar el soporte de C99 para versiones anteriores. Los comstackdores modernos de C soportan esta syntax por defecto.

Alternativa:

Puede cambiar el encabezado para tener una versión en static inline ,

 // mymath.h static inline float clampf(float v, float min, float max) { ... } 

Sin embargo, esto no proporciona una versión no en línea de la función, por lo que el comstackdor puede verse obligado a crear una copia de esta función para cada unidad de traducción.

Notas:

  1. Las reglas de alineación de C99 no son exactamente intuitivas. El artículo ” Funciones en línea en C ” ( espejo ) las describe en detalle. En particular, salte al final y vea “Estrategias para usar funciones en línea”. Prefiero el método # 3, ya que GCC ha estado por defecto al método C99 por un tiempo.

  2. Técnicamente, nunca es necesario poner extern en una statement de función (o definición), ya que extern es el valor predeterminado. Lo puse ahí para darle énfasis.

Debe definir su función como static inline en static inline en el archivo .h:

 static inline float clampf( float v, float min, float max ) { if( v < min ) v = min; if( v > max ) v = max; return v; } 

La función debe estar ausente en el archivo .c.

El comstackdor puede decidir no alinear la función pero hacerla una llamada de función adecuada. Por lo tanto, cada archivo .o generado puede contener una copia de la función.