2012-04-17 21 views
7

Tenemos una macro de función #define FOO(arg) foo(arg) con int foo(const char* bar);. Cuando se define NDEBUG, FOO se define como #define FOO(arg) 0, sin embargo, esto causa muchas advertencias del compilador porque en muchos casos no se usa el valor de retorno de FOO. La solución debería funcionar con los compiladores ANSI C y no causar advertencias. He intentado:Macro de función que se evalúa a cero y se puede utilizar como una declaración

(void)0: no se puede assigend a la variable

static int foo(const char* bar) { return 0; }: causas advertencia función estática no utilizado en algunos módulos

static inline int foo(const char* bar) { return 0; }: sólo funciona con los compiladores C99

Gracias por su ¡ayuda!

edit1: Es como una macro de rastreo y se usa en todo el proyecto. En su mayoría solo se usa como una declaración como FOO("function x called");, pero en algunos casos vi if (FOO("condition a")) { /* some more debug output */ }. Con NDEBUG definido y la optimización habilitada, no debe quedar nada de FOO. No se me ocurrió esto, pero tengo que limpiar este desastre :).

Edit2: Debo añadir que para la liberación gcc construcciones se utilizan estas banderas: -O3 -Wall -ansi

Edit3: Por ahora voy con __inline int dummy() { return 0; }. __inline funciona tanto con VisualC como con GCC en modo ansi.

+2

puedo mostrar más ejemplos de cómo foo() '' se utiliza en el código? – unwind

+3

¿Siempre usa el valor de retorno de, por ejemplo, 'printf()'? – pmg

+0

Si no te importa llamar a foo() y solo quieres asegurarte de que el valor de retorno utilizado sea 0, puedes usar el operador de coma y '#define FOO (arg) (foo (arg), 0)' – Eregrith

Respuesta

2

Lo que podría hacer para evitar que la advertencia es la siguiente:

#ifndef NDEBUG 
    #define FOO(arg) foo(arg) 
#else 
    #define FOO(arg) abs(0) 
#endif 

No estoy diciendo que esto es ideal (usted tiene que asegurarse de stdlib.h se incluye en todas partes, por ejemplo) pero sí previene la advertencia.

+0

Esto podría funcionar, pero como dices no es ideal. Tendría que verificar si el compilador eliminará esto en versiones de lanzamiento. – maep

+0

@maep: Sí, yo también pensé en ese tema. Sin embargo, espero que * cualquier compilador decente lo elimine en versiones de lanzamiento. Por cierto, GCC parece eliminarlo incluso en '-O0'. – Job

+0

Algunos compiladores pueden advertir acerca de llamar a una función pura y no usar el valor de retorno ... –

1

Haría algo que depende de la versión C. En el archivo de cabecera:

#if __STDC_VERSION__ > 199900L 
inline int foo(const char* bar) { return 0; } 
#else 
int foo(const char* bar); 
#endif 

en una unidad de compilación

#if __STDC_VERSION__ < 199900L 
int foo(const char* bar) { return 0; } 
#else 
int foo(const char* bar); 
#endif 

o el uso para la versión más viejas C algo así como la respuesta de Job, que es una función que es seguro para ser optimizado a cabo Pero eso no' t produce la advertencia.

3

I supongo que es un poco compilador de bits dependiente pero esto debería funcionar:

#ifndef NDEBUG 
    #define FOO(arg) foo(arg) 
#else 
    #define FOO(arg) ((int)0) 
#endif 

Se evita la "expresión no tiene ningún efecto" advertencia, no hace nada y su valor cuando se utiliza sigue siendo 0.

EDITADO
parece que es algo no tan portátil para (ahora) que tienen estas enfermedades:

  • (0) o ((int)0) trabajo, al menos en VC 2010.
  • __noop debería funcionar en cualquier versión de VC después de 2003.

VC6 no es un problema porque no emite la advertencia C4555 en absoluto. Para otros compiladores puede usar:

  • ((void)0, 0) Se puede trabajar en una gran cantidad de compiladores (tal vez es el más portátil?).
  • inline int foo(const char* bar) { return 0; } funciona con cualquier otro compilador C99 (como escribió, puede necesitar declararlo como static en gcc).

Para cualquier otro compilador de C prehistóricos utilizar la solución apuntada por @Jobs: abs(0)

+0

Interesante, me pregunto por qué funciona esto ... Tenga en cuenta que en GCC, el reparto ni siquiera es necesario. – Job

+0

Todavía recibo la advertencia con -Wall – maep

+0

@maep ¿Está utilizando VC? Estoy usando 2k10 y no da ninguna advertencia (como señala Job en la mayoría de los compiladores, incluso el elenco no es necesario). ¿Qué clase de advertencia obtienes? –

Cuestiones relacionadas