2010-05-16 16 views
25

Tengo una cantidad de archivos fuente C (archivos .c y .h). los archivos de encabezado contienen varias funciones. De esas funciones, solo parcialmente se usan en un archivo .C de origen. Supongamos que a.h, b.h son archivos de encabezado y a.c y b.c son archivos .c. a.h está incluido en a.c. Pero solo una cantidad de funciones están en a. h se usan y el resto no se usa. Después de la compilación Encuentro siguientes advertencias:Advertencia de función definida pero no utilizada en C

function XXXX defined but not used. 

Pero esas funciones XXXX que no se utilizan en A.C. se utilizan en aC Por lo tanto, no puedo eliminar completamente esas funciones también. Por lo tanto, decidí crear un archivo separado que solo contenga esas funciones XXXX y lo haya incluido donde sea que se use. Esto es crear múltiples números de archivos de encabezado. ¿Puede alguien sugerirme alguna forma efectiva para resolver este problema?

+0

Esto no es un problema para mí. Debe haber algo extraño sobre las declaraciones de su función o sobre cómo está compilando. ¿Puedes dar más detalles? – crazyscot

+2

Creo que necesitamos ver parte del código, ya que esto no sucede normalmente. Consulte los encabezados estándar para ver los ejemplos – Mark

+0

¿Qué compilador está utilizando? – berkay

Respuesta

57

La "Advertencia de función definida pero no utilizada" solo se emite para las funciones con el enlace interno , es decir, las funciones que se declaran como static. Estas funciones solo son accesibles en una unidad de traducción, por lo que el compilador siempre sabe si se usan (en el programa) o no. Si no hace referencia a estas funciones en su unidad de traducción, se sabe que estas funciones no se utilizan y se genera la advertencia.

Usted dice que estas funciones "no se usan en a.c, pero se usan en b.c". Esto no es verdad. Cuando declara (y define) una función como static en el archivo de encabezado, cada unidad de traducción que incluye ese archivo de encabezado obtiene su propia copia interna de la función. Aunque estas funciones se ven absolutamente iguales, todavía son funciones separadas, completamente independientes. El hecho de que tengan el mismo nombre y estén formados por el mismo código no significa nada para el compilador. Entonces, en b.c, obtiene una copia completamente independiente de la función, que se usa (como usted dice), pero la copia completamente independiente en a.c aún no se utiliza.

La pregunta en este caso es por qué está haciendo esto. ¿Por qué en la Tierra está definiendo funciones estáticas en el archivo de encabezado? Si realmente necesita hacer esto (es decirsi realmente desea generar un "clon" interno separado de esta función en cada unidad de traducción), puede evitar la advertencia utilizando algunos medios específicos del compilador. Al igual que en GCC, por ejemplo, puede declarar la función con __attribute__((unused)) y ya no se emitirá la advertencia para esta función.

Pero normalmente uno no necesitaría definir funciones en el archivo de encabezado. Normalmente uno usaría una función con el enlace externo (es decir, no static), defínalo en uno de los archivos .c y coloque la declaración (prototipo) en el archivo de encabezado. El compilador no emitirá ninguna advertencia en este caso, incluso si la función se declara pero no se utiliza en alguna unidad de traducción.

+0

Hacer esto es útil para crear bibliotecas cuando una función es una traducción a otra para darle más significado, como 'bool estático CanHazCheezBurger() {indicadores de retorno & (HAZCHEEZ | HAZBURGER)}'. Es un intento de alinearlo, pero falla porque no hay alineación, solo copia. – Leonardo

6

Si lo que desea es ocultar la advertencia, utilice:

-Wno-unused-function 

Sin embargo, probablemente debería seguir el consejo de caf's answer lugar. Parece que puede haber definido una función cuando solo quería agregar su declaración.

+1

Según mi lectura, supongo que estas advertencias son muy válidas y no deben ocultarse. Creo que Andrey y caf tienen razón en que OP define funciones estáticas en archivos .h. Simplemente ocultar estas advertencias no será útil; es probable que esto cause problemas más grandes en el camino. –

+0

Tienes razón, creo que la respuesta de caf arriba es probablemente correcta. http: // stackoverflow.com/questions/2845748/function-defined-but-not-used-warning-in-c/2846030 # 2846030 He editado el mío ahora. – thomasrutter

5

Parece que su problema es que está definiendo funciones en .h archivos. No hagas eso. En lugar de ello, sólo hay que poner sus declaraciones en el archivo .h, y tienen un archivo que coincida .c que contiene las definiciones de funciones:

COMMON.H:

#ifndef _COMMON_H 
#define _COMMON_H 

int foo(int a, int b); 

int bar(double x, double y, double z); 

#endif /* _COMMON_H */ 

common.c:

#include "common.h" 

int foo(int a, int b) 
{ 
    /* code */ 
} 

int bar(double x, double y, double z) 
{ 
    /* code */ 
} 

Luego su a.c y b.c sh ould #include "common.h", y deberá organizar para tener common.c compilado en el programa completo.

4

Otra posibilidad es definir estas funciones como inline en lugar de static. En este caso, se requiere que se definan en el encabezado para que la definición sea visible en todos los lugares donde se llaman.

El compilador insertará el código en cada lugar donde se usa la función, así que tenga cuidado de que esto sea lo que realmente desea. Here's an answer con una agradable discusión sobre estos intercambios.

+0

Pensé que la palabra clave en línea es solo una sugerencia para el compilador. – Michael

6

Como alternativa a "no hacer eso", tenga en cuenta lo siguiente: un conjunto de funciones que activarán hasta tres advertencias de funciones no utilizadas.

static int get_version_number(void) { return 42; } 
static double hidden_global_variable(void) { return 3.14; } 
static int potential_alternative_to_macro(int x) { return 4 * x; } 

escribir otra función, probablemente basada en el nombre del archivo de cabecera,

static void wno_unused_myheadername(void) 
{ 
    /* don't need to actually call the functions to avoid the warnings */ 
    (void)&get_version_number; 
    (void)&hidden_global_variable; 
    (void)&potential_alternative_to_macro; 
    return; 
} 

Ahora estamos abajo a una alerta función sin usar. Si agrega una llamada a wno_unused_myheadername() en cualquiera de las funciones externas declaradas en el archivo que incluye el encabezado, desaparecerá todo el conjunto de advertencias de funciones no utilizadas. Como ahora están todos usados.

El compilador se eliminará de todas las funciones no utilizadas, incluido wno_unused_myheadername, ya que puede ver todas las definiciones y probablemente pueda determinar que la única llamada a la función wno_unused no hace nada.

He comprobado que lo anterior elimina las advertencias como se esperaba en clang y gcc, su kilometraje puede variar con otros compiladores. No he examinado la salida de asm para investigar cuándo se eliminan las funciones casi no utilizadas.

En cuanto a por qué, una buena razón sería usar muchas funciones pequeñas que son adecuadas para incluir en C89, que no tiene la palabra clave en línea, sin requerir la optimización del tiempo de enlace de su compilador.

Cuestiones relacionadas