¿Cómo puedo silenciar una advertencia sobre las variables no utilizadas?

Tengo una aplicación multiplataforma y en algunas de mis funciones no se utilizan todos los valores pasados ​​a las funciones. Por lo tanto, recibo una advertencia de GCC que me dice que hay variables sin usar.

¿Cuál sería la mejor manera de codificar la advertencia?

¿Un #ifdef alrededor de la función?

#ifdef _MSC_VER void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal qrLeft, qreal qrTop, qreal qrWidth, qreal qrHeight) #else void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal /*qrLeft*/, qreal /*qrTop*/, qreal /*qrWidth*/, qreal /*qrHeight*/) #endif { 

Esto es muy feo, pero parece que la forma en que el comstackdor preferiría.

¿O le asigno cero a la variable al final de la función? (que odio porque está alterando algo en el flujo del progtwig para silenciar una advertencia del comstackdor).

¿Hay una forma correcta?

Puede ponerlo en la expresión ” (void)var; ” (no hace nada) para que un comstackdor vea que se usa. Esto es portátil entre comstackdores.

P.ej

 void foo(int param1, int param2) { (void)param2; bar(param1); } 

O,

 #define UNUSED(expr) do { (void)(expr); } while (0) ... void foo(int param1, int param2) { UNUSED(param2); bar(param1); } 

En gcc, puede usar la directiva de preprocesador __attribute__((unused)) para lograr su objective. Ejemplo:

 int foo (__attribute__((unused)) int bar) { return 0; } 

Su solución actual es la mejor: comente el nombre del parámetro si no lo usa. Esto se aplica a todos los comstackdores, por lo que no tiene que usar el preprocesador para hacerlo especialmente para GCC.

Una forma aún más limpia es simplemente comentar nombres de variables:

 int main(int /* argc */, char const** /* argv */) { return 0; } 

Un compañero de trabajo me acaba de indicar esta linda y pequeña macro aquí

Para facilitar, incluiré la macro a continuación.

 #ifdef UNUSED #elif defined(__GNUC__) # define UNUSED(x) UNUSED_ ## x __attribute__((unused)) #elif defined(__LCLINT__) # define UNUSED(x) /*@unused@*/ x #else # define UNUSED(x) x #endif void dcc_mon_siginfo_handler(int UNUSED(whatsig)) 

C ++ 17 ahora proporciona el atributo [[maybe_unused]] .

http://en.cppreference.com/w/cpp/language/attributes

Bastante agradable y estándar.

Lo siento por una respuesta tan tardía.

gcc no marca estas advertencias por defecto. Esta advertencia debe haberse activado explícitamente pasando -Wunused-parameter al comstackdor o implícitamente al pasar -Wall -Wextra (o posiblemente alguna otra combinación de indicadores).

Las advertencias de parámetros no utilizados pueden simplemente suprimirse pasando el -Wno-unused-parameter al comstackdor, pero tenga en cuenta que este indicador de deshabilitación debe aparecer después de posibles indicadores de habilitación para esta advertencia en la línea de comandos del comstackdor, para que pueda tener efecto.

Actualización de C ++ 17

En C ++ 17 obtenemos el atributo [[maybe_unused]] que está cubierto en [dcl.attr.unused]

El atributo token maybe_unused indica que es posible que un nombre o entidad no se haya usado intencionalmente. Aparecerá a lo sumo una vez en cada lista de atributos y no estará presente la cláusula attribute-argument. …

Ejemplo:

  [[maybe_unused]] void f([[maybe_unused]] bool thing1, [[maybe_unused]] bool thing2) { [[maybe_unused]] bool b = thing1 && thing2; assert(b); } 

Las implementaciones no deben advertir que b no se usa, ya sea que se haya definido o no el NDEBUG. -Final ejemplo]

Para el siguiente ejemplo:

 int foo ( int bar) { bool unused_bool ; return 0; } 

Tanto clang como gcc generan un diagnóstico usando -Wall -Wextra para ambas barras y unused_bool ( Véalo en vivo ).

Al agregar [[maybe_unused]], se silencian los diagnósticos:

 int foo ([[maybe_unused]] int bar) { [[maybe_unused]] bool unused_bool ; return 0; } 

verlo en vivo .

Antes de C ++ 17

En C ++ 11 se podría formar una forma alternativa de la macro UNUSED utilizando una expresión lambda (a través de Ben Deane ) con una captura de la variable no utilizada:

 #define UNUSED(x) [&x]{}() 

La invocación inmediata de la expresión lambda debería optimizarse, dado el siguiente ejemplo:

 int foo (int bar) { UNUSED(bar) ; return 0; } 

podemos ver en godbolt que la llamada se optimiza:

 foo(int): xorl %eax, %eax ret 

forma menos macro y portátil de declarar uno o más parámetros como no utilizados:

 template  inline void unused(Args&&...) {} int main(int argc, char* argv[]) { unused(argc, argv); return 0; } 

El uso de directivas de preprocesador se considera malvado la mayor parte del tiempo. Lo ideal sería evitarlos como la plaga. Recuerde que hacer que el comstackdor comprenda su código es fácil, permitiendo que otros progtwigdores comprendan que su código es mucho más difícil. Algunas docenas de casos como este aquí y allá hacen que sea muy difícil leerlo más tarde o para otros en este momento.

Una forma podría ser juntar los parámetros en algún tipo de clase argumental. A continuación, podría usar solo un subconjunto de variables (equivalente a su asignación de 0 realmente) o tener diferentes especializaciones de esa clase de argumento para cada plataforma. Sin embargo, esto podría no valer la pena, debes analizar si cabría.

Si puede leer plantillas imposibles, puede encontrar sugerencias avanzadas en el libro “Exceptional C ++”. Si las personas que leen tu código pueden hacer que sus habilidades abarquen las locuras que se enseñan en ese libro, entonces tendrías un hermoso código que también se puede leer fácilmente. El comstackdor también sería muy consciente de lo que estás haciendo (en lugar de ocultar todo por preprocesamiento)

En primer lugar, la advertencia es generada por la definición de variable en el archivo de origen, no en el archivo de encabezado. El encabezado puede mantenerse prístino y debería, ya que podría estar usando algo como doxygen para generar la documentación API.

Asumiré que tiene una implementación completamente diferente en los archivos fuente. En estos casos, puede comentar el parámetro ofensivo o simplemente escribir el parámetro.

Ejemplo:

 func(int a, int b) { b; foo(a); } 

Esto puede parecer críptico, por lo que se define una macro como INUSITADA. La forma en que lo hizo MFC es:

 #ifdef _DEBUG #define UNUSED(x) #else #define UNUSED(x) x #endif 

De esta manera, puede ver la advertencia todavía en las versiones de depuración, podría ser útil.

¿No es seguro comentar siempre los nombres de los parámetros? Si no es así, puedes hacer algo como

 #ifdef _MSC_VER # define P_(n) n #else # define P_(n) #endif void ProcessOps::sendToExternalApp( QString sAppName, QString sImagePath, qreal P_(qrLeft), qreal P_(qrTop), qreal P_(qrWidth), qreal P_(qrHeight)) 

Es un poco menos feo

Puedes usar __unused para decirle al comstackdor que esa variable podría no ser utilizada.

 - (void)myMethod:(__unused NSObject *)theObject { // there will be no warning about `theObject`, because you wrote `__unused` __unused int theInt = 0; // there will be no warning, but you are still able to use `theInt` in the future } 

Utilice la bandera del comstackdor, por ejemplo, bandera para GCC: -Wno-unused-variable

Usar un UNREFERENCED_PARAMETER(p) podría funcionar. Sé que está definido en WinNT.h para sistemas Windows y también se puede definir fácilmente para gcc (si aún no lo tiene).

UNREFERENCED PARAMETER(p) se define como

 #define UNREFERENCED_PARAMETER(P) (P) 

en WinNT.h.

Esto funciona bien, pero requiere C ++ 14 No sé si podemos adaptarnos a C ++ 11

 template  void UNUSED(Args&& ...args) { (void)(sizeof...(args)); } 

Encontré que la mayoría de las respuestas presentadas solo funcionan para la variable local no utilizada, y causará un error de comstackción para la variable global estática no utilizada.

Otra macro necesaria para suprimir la advertencia de la variable global estática no utilizada.

 template  const T* UNUSED_VARIABLE(const T& dummy) { return &dummy; } #define UNUSED_GLOBAL_VARIABLE(x) namespace {\ const auto dummy = UNUSED_VARIABLE(x);\ } static int a = 0; UNUSED_GLOBAL_VARIABLE(a); int main () { int b = 3; UNUSED_VARIABLE(b); return 0; } 

Esto funciona porque no se informará ninguna advertencia para la variable global no estática en el espacio de nombres anónimo.

C ++ 11 es obligatorio, aunque

  g++ -Wall -O3 -std=c++11 test.cpp 

En C ++ 11, esta es la solución que estoy usando:

 template inline void Unreferenced(Ts&&...) {} int Foo(int bar) { Unreferenced(bar); return 0; } int Foo2(int bar1, int bar2) { Unreferenced(bar1, bar2); return 0; } 

Verificado para ser portátil (al menos en msvc, clang y gcc modernos) y no producir código adicional cuando las optimizaciones están habilitadas. Sin optimización, la llamada de función extra se realiza y las referencias a los parámetros se copian en la stack, pero no hay macros involucradas.

Si el código adicional es un problema, puede usar esta statement en su lugar:

 (decltype(Unreferenced(bar1, bar2)))0; 

pero en ese punto, una macro proporciona una mejor legibilidad:

 #define UNREFERENCED(...) { (decltype(Unreferenced(__VA_ARGS__)))0; } 

No veo tu problema con la advertencia. Documentarlo en el encabezado de método / función que el comstackdor xy emitirá una advertencia (correcta) aquí, pero que estas variables son necesarias para la plataforma z.

La advertencia es correcta, no hay necesidad de apagarla. No invalida el progtwig, pero debe documentarse, existe una razón.