Desactivar error de advertencia único

115

¿Hay alguna forma de deshabilitar una sola línea de advertencia en un archivo cpp con Visual Studio?

Por ejemplo, si detecto una excepción y no la manejo, obtengo el error 4101 (variable local sin referencia). ¿Hay alguna manera de ignorar esto solo en esa función, pero de lo contrario informarlo en la unidad de compilación? Por el momento, lo coloco #pragma warning (disable : 4101)en la parte superior del archivo, pero eso obviamente lo apaga para toda la unidad.

Galleta
fuente
19
si menciona solo el tipo y no nombra la excepción, no habrá advertencia. Ej catch (const std::exception& /* unnamed */) {.... }. No responde a su pregunta, pero podría resolver su problema.
Sjoerd

Respuestas:

182
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 
Andreas Brinck
fuente
1
@Cookie: sí, funciona para cualquier fragmento de código que pase por el compilador.
Matteo Italia
Para obtener una respuesta más reciente y concisa, consulte la respuesta de Daniel Seither, a continuación.
Dan Nissenbaum
4
clangno parece apoyar esta pragma, pero se puede lograr el mismo efecto con #pragma clang diagnostic push, #pragma clang diagnostic ignored "-Wunused-variable"y #pragma clang diagnostic pop. Consulte "Control de diagnósticos a través de los pragmas" en el Manual del usuario de Clang
rampion
Dado que utilizo esta función con poca frecuencia, cuando lo hago, normalmente termino en esta página para recordarme la sintaxis. Simplemente lo puse alrededor de una llamada a una función obsoleta que puede que nunca se actualice, para que la advertencia no me moleste en las listas del compilador, que escaneo religiosamente.
David A. Gray
Para Visual Studio, el argumento de la línea de comandos es /wd4101. Tenga en cuenta que no hay lo normal :entre la bandera y el número, y no puede hacer una lista de números separados por comas. Para otros compiladores podría ser /nowarn:4101en su lugar.
Jesse Chisholm
89

Si solo desea suprimir una advertencia en una sola línea de código, puede usar el suppress especificador de advertencia :

#pragma warning(suppress: 4101)
// here goes your single line of code where the warning occurs

Para una sola línea de código, esto funciona igual que escribir lo siguiente:

#pragma warning(push)
#pragma warning(disable: 4101)
// here goes your code where the warning occurs
#pragma warning(pop)
Daniel Seither
fuente
8
¡Muy útil! Desafortunadamente, no funciona para una sola línea que incluye un encabezado que genera la advertencia.
Marko Popovic
2
@MarkoPopovic: El suppressespecificador opera en una única línea de código preprocesada . Si la línea siguiente #pragma warning(suppress: ...)es una #includedirectiva (que expande el archivo al que hace referencia su parámetro en la unidad de compilación actual), el efecto se aplica a la primera línea de ese archivo solamente. Esto debería ser obvio, ya que el compilador genera las advertencias. El compilador funciona con código preprocesado.
Inspectable
@IInspectable En ese caso, yo lo llamaría un post-procesado línea de código. preprocesado significa que aún no ha sido traducido por el preprocesador.
void.pointer
2
@voi: La terminación "-ed" significa el participio pasado . Se usa para expresar que algo terminó en el pasado. Una línea "preprocesada" es una línea que ha sido completamente procesada.
IInspectable
29

#pragma push / pop son a menudo una solución para este tipo de problemas, pero en este caso, ¿por qué no elimina la variable sin referencia?

try
{
    // ...
}
catch(const your_exception_type &) // type specified but no variable declared
{
    // ...
}
Matteo Italia
fuente
6
Esta no es una respuesta a la pregunta. Por supuesto, esto podría resolver el problema de OP, pero no ayudará a los futuros lectores con una pregunta similar: "¿cómo desactivo una advertencia específica para una parte específica de mi código?"
Sjoerd
1
@Sjoerd: tres personas ya respondieron la "pregunta oficial" que otras personas pueden buscar, así que en su lugar traté de leer entre líneas y resolver su problema real (llegando un minuto después de tu comentario :P).
Matteo Italia
11
@Sjoerd como futuro lector, doy fe de que esta respuesta, de hecho, me ayudó.
Mołot
2
@ Mołot: como ex escritor, me alegro de que haya ayudado. =)
Matteo Italia
9

Use #pragma warning ( push ), luego #pragma warning ( disable ), luego ingrese su código, luego use #pragma warning ( pop )como se describe aquí :

#pragma warning( push )
#pragma warning( disable : WarningCode)
// code with warning
#pragma warning( pop ) 
diente filoso
fuente
8

Ejemplo:

#pragma warning(suppress:0000)  // (suppress one error in the next line)

Este pragma es válido para C ++ a partir de Visual Studio 2005.
https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

El pragma NO es válido para C # hasta Visual Studio 2005 hasta Visual Studio 2015.
Error: "Deshabilitación o restauración esperada".
(Supongo que nunca llegaron a implementar suppress...)
https://msdn.microsoft.com/en-us/library/441722ys(v=vs.140).aspx

C # necesita un formato diferente. Se vería así (pero no funcionaría):

#pragma warning suppress 0642  // (suppress one error in the next line)

En lugar de suppress, tienes que disabley enable:

if (condition)
#pragma warning disable 0642
    ;  // Empty statement HERE provokes Warning: "Possible mistaken empty statement" (CS0642)
#pragma warning restore 0642
else

Eso es TAN feo, creo que es más inteligente simplemente rediseñarlo:

if (condition)
{
    // Do nothing (because blah blah blah).
}
else
A876
fuente
5

En vez de ponerlo en la parte superior del archivo (o incluso un archivo de cabecera), simplemente envolver el código en cuestión con #pragma warning (push), #pragma warning (disable)y una coincidencia #pragma warning (pop), como se muestra aquí .

Aunque hay algunas otras opciones, incluidas #pramga warning (once).

Christian.K
fuente
5

También se puede usar UNREFERENCED_PARAMETERdefinido en WinNT.H. La definición es simplemente:

#define UNREFERENCED_PARAMETER(P)          (P)

Y utilícelo como:

void OnMessage(WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(wParam);
    UNREFERENCED_PARAMETER(lParam);
}

Por qué lo usaría, podría argumentar que puede omitir el nombre de la variable en sí. Bueno, hay casos (configuración de proyecto diferente, compilaciones de depuración / lanzamiento) en los que la variable podría usarse realmente. En otra configuración, esa variable no se utiliza (y de ahí la advertencia).

Algunos análisis de código estático aún pueden dar una advertencia para esta declaración sin sentido ( wParam;). En ese caso, puede usar DBG_UNREFERENCED_PARAMETERlo mismo que UNREFERENCED_PARAMETERen las compilaciones de depuración y P=Pen la compilación de lanzamiento.

#define DBG_UNREFERENCED_PARAMETER(P)      (P) = (P)
Ajay
fuente
1
tenga en cuenta que desde C ++ 11 tenemos [[maybe_unused]]atributo
metablaster
2

Si desea deshabilitar la unreferenced local variableescritura en algún encabezado

template<class T>
void ignore (const T & ) {}

y use

catch(const Except & excpt) {
    ignore(excpt); // No warning
    // ...  
} 
Alexey Malistov
fuente
2
¿Una llamada de función, solo para suprimir la advertencia? ¿Por qué no haces esto en su lugar (void)unusedVar;?
Nawaz
@Nawaz: Creo que (void)unusedVar;?no cumple con el estándar C ++.
Alexey Malistov
2
Es una expresión cuyo valor es nada. En C ++, incluso puedes hacerlo static_cast<void>(unusedVar).
Nawaz
2
@Nawaz. Explicación de Herb Sutter: herbalutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings
Alexey Malistov
2
§5.2.9 / 4 dice, Any expression can be explicitly converted to type “cv void.” The expression value is discardedsegún el cual puede escribir static_cast<void>(unusedVar)y static_cast<const void>(unusedVar)y static_cast<volatile void>(unusedVar). Todos los formularios son válidos. Espero que aclare tu duda.
Nawaz
2

En ciertas situaciones, debe tener un parámetro con nombre, pero no lo usa directamente.
Por ejemplo, me lo encontré en VS2010, cuando 'e' se usa solo dentro de una decltypedeclaración, el compilador se queja pero debe tener la variable nombrada e.

Todas las no #pragmasugerencias anteriores se reducen a solo agregar una sola declaración:

bool f(int e)
{ 
   // code not using e
   return true;
   e; // use without doing anything
}
Adi Shavit
fuente
1
ahora (en el compilador de MS VS2015) esto hace que el código C4702 sea inalcanzable
Cee McSharpface
2

como mencionó @rampion, si está en clang gcc, las advertencias son por nombre, no por número, y deberá hacer lo siguiente:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
// ..your code..
#pragma clang diagnostic pop

esta información viene de aquí

orion elenzil
fuente