2012-06-20 17 views
14

así que tengo un poco de código como este:reprimir Compilador función de advertencia nunca se declaró hace referencia

void foo (int, int); 

void bar () 
{ 
    //Do Stuff 

    #if (IMPORTANT == 1) 
     foo (1, 2); 
    #endif 

} 

Cuando se realiza una compilación sin "IMPORTANTE" Tengo un compilador de advertencia que se define foo y nunca hace referencia. Lo cual me hizo pensar (ese es el problema).

Para solucionar esto, acabo de agregar el mismo #if (IMPORTANT == 1) alrededor de la definición de la función, etc ... para eliminar la advertencia, y luego comencé a preguntarme si había una forma diferente de suprimir esa advertencia sobre esa función. Estaba mirando attrib "no usado" de GCC y no sabía si las funciones tenían el mismo atributo que podía establecer. ¿Hay alguna otra manera de suprimirlo que suprima esa advertencia solo para esa función y no para el archivo?

+1

Esto debería ser útil, específicamente 'ignored': http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html.Creo que 'push' y' pop' se pueden usar para cubrir solo una función, pero no puedo decir que alguna vez haya tenido que hacerlo. – chris

+2

http://stackoverflow.com/questions/386220/how-can-i-hide-defined-but-not-used-warnings-in-gcc podría ayudar –

+0

Sí, los vi, pero parecen suprimir las advertencias no utilizadas en el archivo completo en lugar de solo esa función específica, a menos que lo lea mal. – Jtello

Respuesta

17

... entonces comencé a preguntarme si había una forma diferente de suprimir esa advertencia sobre esa función.

Puede haber opciones de compilación para suprimir esta advertencia. Sin embargo, un truco es este:

(void)foo; //don't call the function, just use it as function-pointer 

Debería suprimir esta advertencia.

Se puede escribir una macro:

#define SUPPRESS_WARNING(a) (void)a 

void foo(int thisIsAlsoAnUnsedParameter, int usedParameter) 
{ 
    SUPPRESS_WARNING(foo); //better do this inside the definition itself :D 

    SUPPRESS_WARNING(thisIsAlsoAnUnsedParameter); 
} 

Como se puede ver, la definición de foo reprime por sí misma la advertencia.

+0

Funcionó esto es exactamente lo que estaba buscando gracias! Ya tengo una macro similar para suprimir variables individuales, pero no funciones :-) – Jtello

+1

@Jtello: En realidad, la macro que tienes también se puede utilizar para suprimir la función no utilizada. – Nawaz

+1

Esto no funciona para las funciones sobrecargadas ya que no parece que se le permita anular la dirección de una función sobrecargada. – meowsqueak

11

Una solución es a través de atributos de función.

void foo (int, int) __attribute__ ((unused)); 

Esto le dirá gcc no emitir una advertencia sin usar la función para la función foo. Si le preocupa la portabilidad, puede definir una macro UNUSED_FUNCTION_ATTRIBUTE que se expande a __attribute__ ((unused)) con compiladores que admiten atributos, pero se expande a nada en caso contrario.

+1

No necesita el 'UNUSED_FUNCTION_ATTRIBUTE'. Puede definir en el compilador que no admita los atributos de gnu '#define __attribute __ (x)' para hacerlos desaparecer. Tiene la ventaja de que anula todos los atributos (pure, const, malloc, printf, etc.) y no necesita varias macros ad-hoc para todas las variantes. Esa fue la razón original para la extraña sintaxis de doble paréntesis de la extensión '__attribute__' gnu, por lo que incluso los preprocesadores arcaicos sin' VARARGS' podrían neutralizarlos. –

+1

@ PatrickSchlüter - Sí, podrías hacerlo de esa manera, pero eso es esencialmente invocar un comportamiento indefinido. Cualquier identificador, macro o de otro tipo, que comience con un doble guión bajo es propiedad exclusiva de la implementación. Para cumplir con el estándar, el código de nivel de usuario puede usar esos (como extensiones del estándar proporcionado por la implementación), pero el código de usuario no debe modificar ni definir dichos identificadores. –

+0

Esta solución es especialmente útil si la función va a usarse o no depende de una opción de tiempo de compilación, pero aún desea incluir el objeto de función, p. por el bien de las pruebas unitarias. Es entonces una cuestión de modificar el encabezado en tiempo de compilación. – Joost

2

Una buena forma de encapsular cosas dependientes del sistema y del compilador es factorizarlas en los encabezados. Luego, ajusta la ruta de inclusión según el compilador y el sistema, y ​​quizás otras cosas. Puede hacer lo mismo con los archivos de código fuente.

En este caso, la declaración no parece depender de compiler- o sistema, por lo que sólo tiene que añadir la siguiente cabecera común:

// [foo.h] 
#pragma once 
void foo(int, int); 

Con archivo de implementación

// [foo.cpp] 
#include <foo.virtual.cpp> 

A continuación, para la construcción donde algo debería suceder, agregue a la ruta include un directorio que contiene

// [foo.virtual.cpp] 
#include <foo.h> 
void foo(int const a, int const b) 
{ 
    // Do the thing. 
} 

Y para la construcción en el que nada debe suceder, añadir a la ruta de incluir un directorio que contiene

// [foo.virtual.cpp] 
#include <foo.h> 
void foo(int, int) {} 

Si usted tiene miedo de que la llamada de una función de vacío será mucho tiempo, al igual que, un nano-segundo desperdicia, luego simplemente mueva las definiciones a los encabezados y agregue la palabra inline.

Si foo también se utiliza para otros fines, definir una función bar que lo llama para la cosa debe-o-no-debe-ocurrir, y hacer lo anterior para bar en lugar de para foo.

Luego, ha eliminado todas las cosas del preprocesador.

Recuerde que las directivas de preprocesador en el código son poco buenas.

18

Estoy bastante seguro de la opción de alerta relevante es ésta:

-Wunused funciones
avise siempre una función estática se declara pero no está definida o una función estática en línea no se utiliza. Esta advertencia está habilitada por -Wall.

Así que la advertencia se debe dar solamente para una función static, interesante. Tiene sentido. Si una función es static, solo se puede usar dentro del archivo actual, por lo que su definición también debe estar en este archivo.

Y declararlo static inline evita la advertencia, sin recurrir a macros feos o pragmas o atributos específicos del compilador.

+0

Esta debería ser la respuesta aceptada, en mi humilde opinión, ya que el usuario preguntó "¿Hay alguna otra forma de suprimirla que suprima esa advertencia solo para esa función y no para el archivo?" Declarar la función 'static inline' de hecho" evita la advertencia [solo para esa función], sin recurrir a macros feos o pragmas o atributos específicos del compilador ". Si debe tener tales funciones en un archivo de C++ sin usarlas, use la etiqueta 'inline'. – alex

+0

'static inline' no (siempre) suprime esto para clang. – robertwb

1

Me parece una manera de hacerlo que a nivel mundial y funciona también en c

#define SUPPRESS_UNUSED_WARN(var) \ 
    int _dummy_tmp_##var = ((int)(var) & 0) 

entonces usarlo como:

static int foo(int a, int b) 
{ 
    // .... 
} 
SUPRESS_UNUSED_WARN(foo); 
  • que puede ser utilizado en las funciones y variables globales
  • debe colocarse globalmente para poder trabajar
  • no se puede utilizar para las variables locales
+0

Pero si incluye su archivo .h en dos archivos .c, ¿no crearía eso dos variables dummy tmp con el mismo nombre? Y si lo marca como estático, ¿no conduciría eso a otra advertencia de variable no utilizada? – zserge

-3

También puede definir la macro _CRT_SECURE_NO_DEPRECATE en la configuración del proyecto de Visual Studio.

Goto Propiedades del proyecto -> Propiedades de configuración -> C/C++ -> preprocesador -> definiciones del preprocesador

Añadir _CRT_SECURE_NO_DEPRECATE.

Eso es todo!

+0

Comprobé MSDN pero eso no parece estar relacionado. – melpomene

0

Para plataforma de destino durante el uso de ARM, compilador ARM, utilice la siguiente directiva de compilación en torno a la función objetivo de suprimir los mensajes de advertencia:

#pragma diag_suppress 177 
void foo(void) 
{ 
/* does something but is not being called for the current build */ 
} 
8

En C++ 17 puede declarar su función con [[maybe_unused]]:

[[maybe_unused]] void foo (int, int); 

Esto suprimirá la advertencia y es la forma correcta, idiomática de expresar una función posiblemente no utilizada en C++ 17.

Cuestiones relacionadas