Existe uma maneira de suprimir avisos no Xcode?

119

Existe uma maneira de suprimir avisos no Xcode?

Por exemplo, estou chamando um método não documentado e, como o método não está no cabeçalho, recebo um aviso ao compilar. Sei que posso adicioná-lo ao meu cabeçalho para interromper o aviso, mas gostaria de saber se há outra maneira além de adicioná-lo ao cabeçalho (para que eu possa manter os cabeçalhos limpos e padrão) para suprimir o aviso. Um pragma ou algo assim?

kdbdallas
fonte
sim, às vezes você precisa dizer ao compilador para não avisá-lo sobre qualquer variável não utilizada (de acordo com ele), mas na verdade você pode estar usando-a comoBOOL ok = [[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&d interval:NULL forDate:self]; NSAssert1(ok, @"Failed to calculate the first day the month based on %@", self);
thesummersign

Respostas:

145

Para desativar os avisos por arquivo, usando Xcode 3 e llvm-gcc-4.2, você pode usar:

#pragma GCC diagnostic ignored "-Wwarning-flag"

Onde o nome do aviso é algum sinalizador de aviso do gcc.

Isso substitui todos os sinalizadores de aviso na linha de comando. Porém, não funciona com todos os avisos. Adicione -fdiagnostics-show-option ao seu CFLAGS e você pode ver qual sinalizador pode usar para desativar esse aviso.

Robottobor
fonte
Obrigado ! Exatamente o que eu precisava!
Moszi
28
Maneira fácil de obter o código de aviso: vá para o Log Navigator (Command + 7), selecione a compilação superior, expanda o log (o botão '=' à direita) e role até a parte inferior.
Neal Ehardt
1
Para aqueles que se preocupam, uma referência educacional das opções de aviso do GCC: gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Levi
2
Parece que #pragma GCC diagnostic ignored "-Wwarning-flag"já foi removido
allenlinli
1
@allenlinli ainda está lá, você só precisa substituir warning-flagpor um dos avisos listados em gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Fonix de
49

existe uma maneira mais simples de suprimir avisos de variáveis ​​não utilizadas :

#pragma unused(varname)

EDIT: fonte: http://www.cocoadev.com/index.pl?XCodePragmas

ATUALIZAÇÃO: descobri uma nova solução, mais robusta

  1. Abra a guia Projeto> Editar destino ativo> Compilar.
  2. Em User-Defined: encontre (ou crie, se não encontrar) a chave: GCC_WARN_UNUSED_VARIABLEdefina-a como NO.

EDIT-2 Exemplo:

BOOL ok = YES;
NSAssert1(ok, @"Failed to calculate the first day the month based on %@", self);

o compilador mostra um aviso de variável não utilizada para ok.

Solução:

BOOL ok = YES;
#pragma unused(ok)
NSAssert1(ok, @"Failed to calculate the first day the month based on %@", self);

PS: Você também pode definir / redefinir outro aviso GCC_WARN_ABOUT_RETURN_TYPE::YES/NO

o signo de verão
fonte
31
Ainda mais simples é colocar __unused antes da declaração da variável.
Mark Leonard
@mark-leonard deveria ter sido uma resposta separada, estou procurando por isso há dias. Eu tive que começar a ler comentários em desespero. Obrigado.
Repouso
35

Para gcc você pode usar

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow-ivar"
// your code
#pragma GCC diagnostic pop

Você pode aprender sobre o pragma GCC aqui e para obter o código de aviso de um aviso, vá para o Report Navigator (Command + 9), selecione a compilação superior, expanda o log (o botão '=' à direita) e role até o embaixo e lá o seu código de aviso está entre colchetes como este[-Wshadow-ivar]

Para clang você pode usar

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow-ivar"
// your code
#pragma clang diagnostic pop
Inder Kumar Rathore
fonte
4
Clang suporta o pragma do GCC para compatibilidade com o código-fonte existente. Então você só precisa escrever pragma no formato gcc.
Allen
1
A partir do Xcode 5.0, o Clang foi o único compilador fornecido. Portanto, você pode precisar usar o pragma de formato do clang agora.
allenlinli
27

Para suprimir um aviso para um arquivo individual, faça o seguinte:

selecione o arquivo no projeto xcode. pressione obter informações vá para a página com as opções de compilação e digite -Wno- para negar um aviso:

-Wno-

por exemplo

-Wno-unused-parameter

Você pode obter o nome do aviso se olhar nas configurações do projeto, olhar os avisos do GCC localizados na parte inferior da página da guia de compilação, clicando em cada aviso, ele informará o nome do parâmetro de aviso:

por exemplo

Avisa sempre que um parâmetro de função não é usado, além de sua declaração. [GCC_WARN_UNUSED_PARAMETER, -Wunused-parameter]

AndersK
fonte
2
Esta é uma solução excelente para quando você inclui o código de uma base de código que não deseja modificar e que aconteça para acionar avisos do compilador ...
Mark Beaton,
Parece uma ótima maneira, mas alguma ideia de como fazer isso no XCode 4
Santthosh
2
Encontrei minha solução aqui para o XCode 4 stackoverflow.com/questions/6057192/…
Santthosh de
se você precisar de um aviso de supress para apenas um problema, como o meu: ...m:45:69: Incompatible pointer types sending...abri a explicação da compilação e encontrei este aviso: [-Wincompatible-pointer-types]acabei de renomeá-lo para -Wno-incompatible-pointer-typese adicionei como um sinalizador ao meu .marquivo ... boom, não há mais avisos ... +10 if eu poderia
Nicos Karalis
5

Com Objective-C, vários erros graves aparecem apenas como avisos. Não apenas nunca desabilito os avisos, mas também ativo "Tratar avisos como erros" (-Werror).

Todo tipo de aviso em seu código pode ser evitado fazendo as coisas corretamente (normalmente lançando objetos para o tipo correto) ou declarando protótipos quando você precisar deles.

Matt Gallagher
fonte
14
Embora este seja um bom conselho geral, ele não responde à pergunta. Nem todos os avisos são críticos ou sérios; muitos são bastante triviais. Suponha que seja necessário usar uma biblioteca de terceiros e não possa modificá-la, por qualquer motivo (base de código legada, código destinado a ser vinculado por terceiros, estipulação de chefe, etc.) Suprimir avisos triviais específicos é bastante aceitável nesses casos.
Paul Legato,
5

Para se livrar do aviso: tente criar uma interface de categoria para o objeto em questão

@interface NSTheClass (MyUndocumentedMethodsForNSTheClass)

-(id)theUndocumentedMethod;
@end
...

@implementation myClass : mySuperclass

-(void) myMethod {
...
   [theObject theUndocumentedMethod];
...
}

Como um aparte, eu desaconselho fortemente chamar métodos não documentados no código de envio. A interface pode e vai mudar, e a culpa será sua.

Mark Pauley
fonte
Eu também faço isso. Chamo minha categoria de "Privado" e coloco no topo do arquivo .m ... Serve como uma forma de encaminhar declarar os métodos que só são usados ​​dentro do arquivo. Eu concordo que um arquivo de cabeçalho privado seria mais padrão, mas ter que pular constantemente entre os arquivos por algo que realmente deveria estar totalmente contido (privado) para a implementação é irritante.
Pat Niemeyer
Então, acontece que você pode usar o velho truque do C de apenas implementar o método antes que qualquer coisa o use. Então você tem um método local de arquivo. Eu acho que não é privado, portanto, outros arquivos podem enviar uma mensagem para o seletor que você definir desta forma.
Mark Pauley
3

Crie um novo arquivo de cabeçalho separado chamado 'Undocumented.h' e adicione-o ao seu projeto. Em seguida, crie um bloco de interface para cada classe em que deseja chamar funções não documentadas e dê a cada uma uma categoria de '(Não documentado)'. Em seguida, basta incluir esse arquivo de cabeçalho em seu PCH. Desta forma, seus arquivos de cabeçalho originais permanecem limpos, há apenas um outro arquivo para manter e você pode comentar uma linha em seu PCH para reativar todos os avisos novamente.

Eu também uso este método para funções depreciadas em 'Depreciated.h' com uma categoria de '(Depreciated)'.

a melhor parte é que você pode ativar / desativar seletivamente os avisos individuais, comentando ou descomentando os protótipos individuais.

Mark A. Donohoe
fonte
1

Suprimir esse aviso específico não é seguro. O compilador precisa saber os tipos de argumentos e retorna a um método para gerar o código correto.

Por exemplo, se você está chamando um método como este

[foo doSomethingWithFloat: 1.0];

que leva um float, e não há nenhum protótipo visível, então o compilador vai adivinhar que o método leva um double, não um float. Isso pode causar travamentos e valores interpretados incorretamente. No exemplo acima, em uma pequena máquina endian como as máquinas intel, o método do receptor veria 0 aprovado, não 1.

Você pode ler o motivo nos documentos i386 da ABI ou pode apenas corrigir seus avisos. :-)

Ken
fonte
2
Bom conselho, mas na verdade não responde à pergunta, conforme acima.
Paul Legato