Desativar erro de aviso único

115

Existe uma maneira de desativar apenas uma única linha de aviso em um arquivo cpp com o visual studio?

Por exemplo, se eu detectar uma exceção e não lidar com ela, recebo o erro 4101 (variável local não referenciada). Existe uma maneira de ignorar isso apenas nessa função, mas caso contrário, relatá-lo na unidade de compilação? No momento, eu coloquei #pragma warning (disable : 4101)no topo do arquivo, mas obviamente apenas desativa a unidade inteira.

Biscoito
fonte
19
se você mencionar apenas o tipo e não nomear a exceção, não haverá nenhum aviso. Ex catch (const std::exception& /* unnamed */) {.... }. Não responde à sua pergunta, mas pode resolver o seu problema.
Sjoerd

Respostas:

182
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 
Andreas Brinck
fonte
1
@Cookie: sim, funciona para qualquer parte do código que passa pelo compilador.
Matteo Italia
Para uma resposta mais recente e concisa, consulte a resposta de Daniel Seither, abaixo.
Dan Nissenbaum
4
clangnão parece apoiar este pragma, mas você pode conseguir o mesmo efeito com #pragma clang diagnostic push, #pragma clang diagnostic ignored "-Wunused-variable"e #pragma clang diagnostic pop. Consulte "Controlando diagnósticos por meio de pragmas" no Manual do usuário do Clang
aumento em
Como não uso esse recurso com frequência, quando o faço, geralmente acabo nesta página para me lembrar da sintaxe. Acabei de colocá-lo em torno de uma chamada para uma função obsoleta que pode nunca ser atualizada, para que o aviso não me incomode nas listagens do compilador, que eu examino religiosamente.
David A. Gray
Para Visual Studio, o argumento da linha de comando é /wd4101. Observe que não há normal :entre a bandeira e o número, e você não pode fazer uma lista de números separados por vírgulas. Para outros compiladores, pode ser /nowarn:4101.
Jesse Chisholm
89

Se você deseja suprimir um aviso em uma única linha de código, pode usar o suppress especificador de aviso :

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

Para uma única linha de código, isso funciona da mesma forma que escrever o seguinte:

#pragma warning(push)
#pragma warning(disable: 4101)
// here goes your code where the warning occurs
#pragma warning(pop)
Daniel Seither
fonte
8
Muito útil! Infelizmente, isso não funciona para uma única linha que inclui um cabeçalho que gera o aviso.
Marko Popovic
2
@MarkoPopovic: O suppressespecificador opera em uma única linha de código pré-processada . Se a linha a seguir #pragma warning(suppress: ...)for uma #includediretiva (que expande o arquivo referenciado por seu parâmetro na unidade de compilação atual), o efeito se aplica apenas à primeira linha desse arquivo. Isso deve ser óbvio, uma vez que os avisos são gerados pelo compilador. O compilador opera em código pré-processado.
Inspecionável de
@IInspectable Nesse caso, eu a chamaria de linha de código pós-processada . pré-processado significa que ainda não foi traduzido pelo pré-processador.
void.pointer
2
@voi: A desinência "-ed" significa o particípio passado . É usado para expressar que algo terminou no passado. Uma linha "pré-processada" é uma linha que foi totalmente processada.
Inspecionável
29

#pragma push / pop costuma ser uma solução para esse tipo de problema, mas, neste caso, por que você simplesmente não remove a variável não referenciada?

try
{
    // ...
}
catch(const your_exception_type &) // type specified but no variable declared
{
    // ...
}
Matteo Italia
fonte
6
Esta não é uma resposta à pergunta. Concedido, isso pode resolver o problema do OP, mas não ajudará futuros leitores com uma pergunta semelhante: "como faço para desligar um aviso específico para uma parte específica do meu código?"
Sjoerd de
1
@Sjoerd: três pessoas já responderam a "pergunta oficial" que outras pessoas podem pesquisar, então em vez disso tentei ler nas entrelinhas e resolver o problema real (chegando um minuto após o seu comentário :P).
Matteo Italia
11
@Sjoerd como futuro leitor, atesto que essa resposta de fato me ajudou.
Mołot de
2
@ Mołot: como ex-escritor, fico feliz que tenha ajudado. =)
Matteo Italia
9

Use #pragma warning ( push ), então #pragma warning ( disable ), coloque seu código e use #pragma warning ( pop )conforme descrito aqui :

#pragma warning( push )
#pragma warning( disable : WarningCode)
// code with warning
#pragma warning( pop ) 
dente afiado
fonte
8

Exemplo:

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

Este pragma é válido para C ++ começando com Visual Studio 2005.
https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

O pragma NÃO é válido para C # até Visual Studio 2005 até Visual Studio 2015.
Erro: "Desativação ou restauração esperada".
(Acho que eles nunca implementaram suppress...)
https://msdn.microsoft.com/en-us/library/441722ys(v=vs.140).aspx

C # precisa de um formato diferente. Ficaria assim (mas não funcionaria):

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

Em vez de suppress, você deve disablee enable:

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

Isso é TÃO feio, acho que é mais inteligente apenas reformulá-lo:

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

Em vez de colocá-lo em cima do arquivo (ou mesmo de um arquivo de cabeçalho), apenas envolva o código em questão com #pragma warning (push), #pragma warning (disable)e uma correspondência #pragma warning (pop), conforme mostrado aqui .

Embora existam algumas outras opções, incluindo #pramga warning (once).

Christian.K
fonte
5

Também se pode usar UNREFERENCED_PARAMETERdefinido em WinNT.H. A definição é apenas:

#define UNREFERENCED_PARAMETER(P)          (P)

E use-o como:

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

Por que você o usaria, você pode argumentar que pode simplesmente omitir o próprio nome da variável. Bem, há casos (configuração de projeto diferente, compilações de depuração / liberação) onde a variável pode realmente ser usada. Em outra configuração, essa variável permanece sem uso (e, portanto, o aviso).

Algumas análises de código estático ainda podem dar um aviso para esta declaração sem sentido ( wParam;). Nesse caso, você pode usar o DBG_UNREFERENCED_PARAMETERque é o mesmo que UNREFERENCED_PARAMETERem compilações de depuração e faz P=Pna compilação de lançamento.

#define DBG_UNREFERENCED_PARAMETER(P)      (P) = (P)
Ajay
fonte
1
note que desde C ++ 11 temos [[maybe_unused]]attribute
metablaster
2

Se você deseja desativar a unreferenced local variableescrita em algum cabeçalho

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

E use

catch(const Except & excpt) {
    ignore(excpt); // No warning
    // ...  
} 
Alexey Malistov
fonte
2
Uma chamada de função, apenas para suprimir o aviso? Por que você não faz isso (void)unusedVar;:?
Nawaz
@Nawaz: Acho que (void)unusedVar;?não é compatível com o padrão C ++.
Alexey Malistov
2
É uma expressão cujo valor não é nada. Em C ++, você pode até fazer static_cast<void>(unusedVar).
Nawaz
2
@Nawaz. Explicação de Herb Sutter: herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings
Alexey Malistov
2
§5.2.9 / 4 diz, de Any expression can be explicitly converted to type “cv void.” The expression value is discardedacordo com o qual você pode escrever static_cast<void>(unusedVar)e static_cast<const void>(unusedVar)e static_cast<volatile void>(unusedVar). Todos os formulários são válidos. Espero que esclareça sua dúvida.
Nawaz
2

Em certas situações, você deve ter um parâmetro nomeado, mas não o usa diretamente.
Por exemplo, eu encontrei isso no VS2010, quando 'e' é usado apenas dentro de uma decltypeinstrução, o compilador reclama, mas você deve ter a variável nomeada e.

Todas as não #pragmasugestões acima se resumem a apenas adicionar uma única declaração:

bool f(int e)
{ 
   // code not using e
   return true;
   e; // use without doing anything
}
Adi Shavit
fonte
1
agora (no compilador MS VS2015) isso faz com que o código C4702 não possa ser alcançado
Cee McSharpface
2

como @rampion mencionou, se você estiver no clang gcc, os avisos são por nome, não por número, e você precisará fazer:

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

esta informação vem daqui

orion elenzil
fonte