usuario - ¿Cómo declarar una función en línea en el proyecto de múltiples archivos C99?
todas las funciones de arduino (3)
Quiero definir una función en línea en un proyecto, compilado con c99. ¿Cómo puedo hacerlo? Cuando declaro la función en un archivo de encabezado y doy los detalles en un archivo .c, la definición no es reconocida por otros archivos. Cuando coloco la función explícita en un archivo de encabezado, tengo un problema porque todos los archivos .o que lo usan tienen una copia de la definición, por lo que el vinculador me da un error de "definición múltiple".
Lo que estoy tratando de hacer es algo como:
header.h
inline void func()
{
do things...
}
lib1.c
#include "header.h"
...
lib2.c
#include "header.h"
con una utilidad que usa tanto lib1.o como lib2.o
Creo que no necesita usar la palabra en línea cuando está definiendo y declarando la función dentro del archivo de encabezado, el compilador generalmente lo toma como en línea por defecto, a menos que sea demasiado largo, en cuyo caso será lo suficientemente inteligente como para tratarlo Como una función normal.
Creo que la definición múltiple puede deberse a la falta de un Include Guard en el archivo de encabezado.
Deberías usar algo como esto en el encabezado:
#ifndef HEADERNAME_H
#define HEADERNAME_H
void func()
{
// do things...
}
#endif
Desafortunadamente, no todos los compiladores están cumpliendo completamente con C99 en ese punto, incluso si afirman que lo serían.
Una forma conforme de hacerlo es
// header file. an inline declaration alone is
// not supposed to generate an external symbol
inline void toto(void) {
// do something
}
// in one .c file, force the creation of an
// external symbol
extern inline void toto(void);
Las nuevas versiones de gcc, por ejemplo, funcionarán bien con eso.
Puede salirse con la suya para otros compiladores (pretendientes) definiendo algo como
#ifdef PRETENDER
# define inlDec static
# define inlIns static
#else
# define inlDec
# define inlIns extern
#endif
// header file. an inline declaration alone is
// not supposed to generate an external symbol
inlDec inline void toto(void) {
// do something
}
// in one .c file, force the creation of an
// external symbol
inlIns inline void toto(void);
Editar:
compiladores con soporte para C99 (generalmente la opción -std=c99
) que conozco
- gcc (versiones> = 4.3 IIRC) implementa el modelo en
inline
correcto - pcc también es correcta
- ggc <4.3 necesita una opción especial para implementar el modelo correcto, de lo contrario, utilizan su propio modelo que da como resultado múltiples símbolos definidos si no tiene cuidado
- icc solo emite símbolos en cada unidad si no tiene especial cuidado. Pero estos símbolos son símbolos "débiles", por lo que no generan conflicto. Simplemente explotan tu código.
- opencc, AFAIR, sigue el antiguo modelo específico de gcc
- clang no emite símbolos para las funciones en
inline
, a menos que tenga una declaraciónextern
y use el puntero de función en una unidad de compilación. - tcc simplemente ignora la palabra clave en
inline
Si se usa solo, en C99 inline
requiere que la función se defina en la misma unidad de traducción que se usa (por lo tanto, si la usa en lib1.c, debe definirse en lib1.c).
También puede declarar un método como en static inline
(y colocar la definición en un archivo de encabezado compartido entre dos archivos de origen). Esto evita el problema de la definición múltiple y permite al compilador alinear el archivo en todas las unidades de traducción donde se usa (lo que puede o no puede hacer si solo declara la función en una unidad de traducción).
Consulte: http://www.greenend.org.uk/rjk/2003/03/inline.html