thetna
Recibo la advertencia: function used but not defined
. tengo static
en el archivo de encabezado decir
__inline__a.h
. El archivo de encabezado está incluido en a.c
. Me gustaría poner todas esas funciones en línea que están en los archivos de encabezado en el .c
archivos El siguiente código da la idea de mi problema.
Código original:
ah:
static __inline__ function1(){
function definition;
}
Cambié:
ah:
static function1();
C.A:
#include "a.h"
static function1(){
function definition;
}
Al hacer lo anterior, recibí la advertencia:
warning: function function1 is used but not defined.
¿Podría decirme por qué recibo esa advertencia? Me gustaría transferir todo el __inline__
función en el .c
para que no reciba la advertencia:
warning: function1 is could not be inlined, code size may grow.
Gracias por adelantado
Ha declarado que la función es estática. Esto significa que solo es visible dentro de la unidad de compilación actual. En otras palabras: la implementación solo es visible dentro del a.c
expediente. Necesitas quitar el static
palabra clave tanto en el a.h
y a.c
para que otros archivos .c puedan ver la función. Debe especificar un valor de retorno, por ejemplo void function1();
porque implícitamente es int
si no especificó uno.
thkala
Funciones declaradas static
Dentro de un .c
solo son visibles/utilizables dentro de ese archivo. Si no se usan en él, entonces son efectivamente código muerto y el compilador le advierte sobre este hecho. En GCC puedes usar el unused
atributo de función para suprimir esta advertencia:
static int __attribute__((unused)) function1() {
...
}
EDITAR:
En general, debe seguir las siguientes pautas con respecto a las funciones en línea:
-
Si se utilizan en varios archivos C, declararlos
static
y tener su definición en un archivo de encabezado incluido. Eso permite que todo.c
archivos que incluyen ese encabezado para tener su propio privado definición de la función, lo que permite que el compilador la alinee. Solitariostatic
función prototipos tienen poco o ningún sentido en un archivo de encabezado que será utilizado por varios archivos de origen, ya que faltarán sus definiciones reales. -
Si no están destinados a ser reutilizados, tenga su definición (y, si es necesario, su prototipo) en el
.c
archivo donde se supone que deben ser utilizados.
Si GCC se queja de no poder alinear una función, debido al tamaño de la función:
-
Pregúntate si tu De Verdad necesita que esa función esté en línea; según mi experiencia, el compilador generalmente sabe mejor.
-
Si realmente, realmente quieres esa función en línea, el
always_inline
atributo de función puede ser de utilidad. Es posible que también deba proporcionar un valor no predeterminado-finline-limit=n
opción a GCC para aumentar el tamaño permitido para las funciones en línea.
Ver también este para obtener información adicional sobre las funciones en línea y algunos posibles errores relacionados con su uso.
EDITAR 2:
Si tienes un static inline
función definida en un archivo de encabezado compartido y desea convertirlo en una función normal, a falta de una palabra mejor, debe:
-
Seleccione un
.c
archivo donde la presencia de esa función tiene sentido (es decir, ponerlo con otras funciones relacionadas). -
Quitar el
static
yinline
palabras clave a partir de su definición y Muevete la definición del encabezado en ese archivo. -
Quitar el
static
yinline
palabras clave de su prototipo y ponerlo en el archivo de cabecera.
Felicitaciones, ahora tiene una función normal disponible públicamente.
Descargo de responsabilidad: acaba de crear una función que era privada para varios archivos, público a todo su programa. Si hay otro símbolo público (variable o función) con el mismo nombre, puede obtener errores al vincular o incluso un comportamiento extraño en el tiempo de ejecución. Has sido advertido…
-
Gracias por la respuesta descriptiva. En realidad, no quiero en línea la función. Entonces, manteniendo la misma funcionalidad, me gustaría eliminar el en línea. Dado que estoy definiendo la función en línea particular en el archivo C, ¿la palabra clave estático delante de la función que crea el problema?>
– thetna
2 abr 2011 a las 23:34
-
static
en una definición de función hace que esa función privado a ese.c
archivo solamente. Si esa función no se usa realmente en ese.c
file es un código muerto, razón por la cual el compilador se queja.– Thkala
2 abr 2011 a las 23:37
pmg
Declarar la función normalmente en el archivo de encabezado
ah
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
void function1(void);
#endif
Defina la función en un solo archivo de código sin static
C.A
#include "a.h"
void function1(void) {
/* function definition */
}
y llame a la función desde otros archivos, después de incluir el encabezado
antes de Cristo
#include "a.h"
void quux(void) {
function1(); /* call regular function */
}
La forma en que tenías antes (static
e implementación en el archivo de encabezado) funcionó porque cada archivo de código que incluía ese encabezado tenía su propia versión de la función; diferente a cualquier otra función del mismo nombre en cualquier otro archivo (pero haciendo exactamente lo mismo).
-
¿Quiere decir que no debería mantener el prototipo de función en el archivo de encabezado? El archivo de encabezado particular también se incluye en los diferentes archivos C. ¿O es la palabra clave estático está haciendo la diferencia?
– thetna
2 abr 2011 a las 23:10
-
El archivo de encabezado es para ayudar a otros archivos (unidades de traducción) a conocer la forma correcta de llamar a la función. Si la función solo está disponible para un solo archivo .c (el
static
), no tiene sentido agregar el prototipo al archivo .h.– pmg
2 abr 2011 a las 23:13
-
Solo quiero eliminar la palabra clave en línea manteniendo la funcionalidad del código igual que antes. ¿Qué sugieres en este caso? Esas funciones en línea también se llamaron en otros archivos C. ¿No es necesario definirlo en el archivo de encabezado en este caso?
– thetna
2 abr 2011 a las 23:22
-
Entonces no puedes declarar la función.
static
. Mantenga el prototipo en un solo archivo de encabezado (a.h
), la definición en un solo archivo de código (a.c
) y#include "a.h"
en los otros archivos de código.– pmg
2 abr 2011 a las 23:29
Corrija el formato del código en su código; ¡es un desastre!
– Carreras de ligereza en órbita
2 abr 2011 a las 23:03
Recuerde proporcionar un tipo de devolución para cada función: está utilizando C99 y C99 lo requiere.
–Jonathan Leffler
2 abr 2011 a las 23:09