scratch - how to program c++
¿Cómo puedo silenciar una advertencia sobre las variables no utilizadas? (18)
¿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
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 compilador 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 programa para silenciar una advertencia del compilador).
¿Hay una forma correcta?
C ++ 17 ahora proporciona el atributo [[maybe_unused]]
.
http://en.cppreference.com/w/cpp/language/attributes
Bastante agradable y estándar.
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 compilador comprenda su código es fácil, permitiendo que otros programadores 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 compilador también sería muy consciente de lo que estás haciendo (en lugar de ocultar todo por preprocesamiento)
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
En gcc, puede usar la directiva de preprocesador __attribute__((unused))
para lograr su objetivo. Ejemplo:
int foo (__attribute__((unused)) int bar) {
return 0;
}
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.
Encontré que la mayoría de las respuestas presentadas solo funcionan para la variable local no utilizada, y causará un error de compilació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 <typename T>
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
Esto funciona bien, pero requiere C ++ 14 No sé si podemos adaptarnos a C ++ 11
template <typename ...Args>
void UNUSED(Args&& ...args)
{
(void)(sizeof...(args));
}
Lo siento por una respuesta tan tardía.
gcc no gcc estas advertencias por defecto. Esta advertencia debe haberse activado explícitamente pasando -Wunused-parameter
al compilador 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 compilador, 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 compilador, para que pueda tener efecto.
No veo tu problema con la advertencia. Documentarlo en el encabezado de método / función que el compilador 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 programa, pero debe documentarse, existe una razón.
Puede ponerlo en la expresión " (void)var;
" (no hace nada) para que un compilador vea que se usa. Esto es portátil entre compiladores.
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);
}
Puedes usar __unused
para decirle al compilador 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
}
Su solución actual es la mejor: comente el nombre del parámetro si no lo usa. Esto se aplica a todos los compiladores, por lo que no tiene que usar el preprocesador para hacerlo especialmente para GCC.
Un compañero de trabajo me acaba de indicar esta linda y pequeña macro here
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))
Una forma aún más limpia es simplemente comentar nombres de variables:
int main(int /* argc */, char const** /* argv */) {
return 0;
}
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.
Utilice la bandera del compilador, por ejemplo, bandera para GCC: -Wno-unused-variable
forma menos macro y portátil de declarar uno o más parámetros como no utilizados:
template <typename... Args> inline void unused(Args&&...) {}
int main(int argc, char* argv[])
{
unused(argc, argv);
return 0;
}