C99 se refiere a la función en línea: referencia indefinida a XXX y ¿por qué debería ponerla en el encabezado?

¿Cumple gcc con el modelo en línea especificado en el estándar C99?

He navegado un poco de información sobre este problema. Pero no entiendo por qué la función en línea se debe especificar con “extern” o “static”.

En el archivo .c, llamar a una función en línea definida en la misma unidad de traducción provoca un error. ¿Cuál es la razón del comportamiento del comstackdor?

Encontré una publicación ¿Es “inline” sin “static” o “extern” útil en C99?

¿Qué significa esto?

Si se produce una llamada a alguna función de función con enlace externo cuando se ve una definición en línea, el comportamiento es el mismo que si se hiciera una llamada a otra función, digamos __func, con enlace interno.

La semántica en línea en C99 es un poco confusa, debo admitir. El cuantificador en inline permite definir definiciones alternativas de una función.

Si una función se define en todas partes como simplemente en inline tanto en las declaraciones como en la definición, esta definición es válida solo en la unidad de traducción local. En la norma C99, esta definición es muy vaga, pero en la práctica la mayoría de los comstackdores implementan esto en un sentido similar al de static inline . Esencialmente, solo en inline sobrescribe cualquier otra función con el mismo nombre en cualquier otra unidad de enlace. Por lo tanto, si declara una función simplemente en inline en un encabezado, el comstackdor esperará encontrar una definición de la misma en la misma unidad de comstackción y le dará un error más adelante si no lo hace.

Ahora, si una función debe estar tanto en línea como disponible en otras unidades de traducción, entonces debe definirse como extern en la statement del encabezado. Entonces el comstackdor no lo buscará solo en la unidad de comstackción actual.

static inline es, con mucho, la definición más portátil en este momento y está limitada a la unidad de traducción actual. Esto se encuentra a menudo en los encabezados junto con la definición de la función real.

inline función en inline pertenece al encabezado, de modo que todas las unidades de comstackción ven el código.

Si el código no puede estar en línea por cualquier razón, el ejecutable final debe tener una versión de la función a la que se puede vincular. Esto tendría que “crear instancias” en solo una unidad de comstackción (archivo .c) con algo como

 extern inline void toto(int bla); 

lo que obliga a un símbolo a ser incluido en esa unidad.

Puedes encontrar más sobre eso aquí

Tienes que pensar en cómo se enlaza el código. Primero se comstack el código fuente a los archivos objeto. Estos archivos de objetos solo contienen el código binario de cada función que se encuentra al indexar el nombre de la función (o el nombre mutilado en c ++). Los archivos de objetos NO contienen información sobre si la función debe estar en línea o no. Por lo tanto, esta información se debe colocar en el archivo de encabezado que se usa en combinación con el archivo de objeto durante el proceso de vinculación. Al usar static delante de la inline en su archivo .c , está haciendo que la función sea visible a cualquier otra función que use esa función static inline ANTES del proceso de comstackción. Pero una vez que estas funciones se comstackn en un archivo de objeto, no pueden “en línea” con otras funciones de otros archivos de objeto.

Entonces, al solo incluir la palabra clave en inline en sus definiciones de encabezado (archivo .h ) en lugar de su archivo fuente ( .c ), puede “en línea” las funciones de un archivo de objeto dentro de otras funciones de otro archivo de objeto en el proceso de vinculación.