No Visual C ++, é possível usar #pragma warning (disable: ...)
. Também descobri que no GCC você pode substituir os sinalizadores por compilador de arquivo . Como posso fazer isso para "próxima linha" ou com semântica push / pop em torno de áreas de código usando o GCC?
c
gcc
compiler-warnings
pragma
Matt Joiner
fonte
fonte
Respostas:
Parece que isso pode ser feito . Não consigo determinar a versão do GCC que foi adicionada, mas ocorreu antes de junho de 2010.
Aqui está um exemplo:
fonte
push
e doispop
s - pode ser outropush
no início está faltando?Para compensar tudo, este é um exemplo de desativar temporariamente um aviso:
Você pode verificar a documentação do GCC sobre pragmas de diagnóstico para obter mais detalhes.
fonte
gcc-4.9
simplesmente ignora essa linha completamente.TL; DR : Se funcionar, evite ou use especificadores como o
__attribute__
contrário_Pragma
.Esta é uma versão curta do meu artigo de blog Suprimindo avisos no GCC e no Clang .
Considere o seguinte
Makefile
para criar o seguinte
puts.c
código fonteEle não será compilado porque
argc
não está sendo usado e as configurações são graves (-W -Wall -pedantic -Werror
).Existem 5 coisas que você pode fazer:
__attribute__
_Pragma
#pragma
Melhorando a fonte
A primeira tentativa deve verificar se o código fonte pode ser aprimorado para se livrar do aviso. Nesse caso, não queremos alterar o algoritmo apenas por causa disso, pois
argc
é redundante com!*argv
(NULL
após o último elemento).Usando um especificador de declaração, como
__attribute__
Se você tiver sorte, o padrão fornece um especificador para a sua situação, como
_Noreturn
.__attribute__
é uma extensão proprietária do GCC (suportada pelo Clang e outros compiladoresarmcc
) e não será compreendida por muitos outros compiladores. Coloque__attribute__((unused))
dentro de uma macro se você quiser código portátil._Pragma
operador_Pragma
pode ser usado como uma alternativa para#pragma
.A principal vantagem do
_Pragma
operador é que você pode colocá-lo dentro de macros, o que não é possível com a#pragma
diretiva.Desvantagem: é quase uma bomba nuclear tática, pois funciona com base em linhas, em vez de em declarações.
O
_Pragma
operador foi introduzido no C99.#pragma
directiva.Poderíamos alterar o código fonte para suprimir o aviso para uma região de código, normalmente uma função inteira:
Desvantagem: é quase uma bomba nuclear tática, pois funciona com base em linhas, em vez de em declarações.
Observe que uma sintaxe semelhante existe no clang .
Suprimindo o aviso na linha de comandos para um único arquivo
Poderíamos adicionar a seguinte linha ao
Makefile
para suprimir o aviso especificamente para o put:Provavelmente, não é o que você deseja no seu caso específico, mas pode ajudar outras leituras que estão em situações semelhantes.
fonte
improving the source
também funcionaria para mudar a declaração de main paraint main(int, const char* argv[]) { ... }
não dando um nome ao argumento, você diz ao compilador que ele não será utilizado.gcc
e tambémclang
.#define UNUSED(x) ((void)x)
usada para silenciar avisos. Eu acho que foi no ReactOS?_Pragma("GCC diagnostic pop") \
deveria ser apenas_Pragma("GCC diagnostic pop")
eu acho.Isso deve fazer o truque para gcc, clang e msvc
Pode ser chamado com, por exemplo:
consulte https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html , http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas e https://msdn.microsoft .com / de-DE / library / d9x1s805.aspx para obter mais detalhes
Você precisa pelo menos da versão 4.02 para usar esse tipo de pragmas para o gcc, não tenho certeza sobre o msvc e não comenta as versões.
Parece que o manuseio do pragma push pop para o gcc está um pouco quebrado. Se você ativar o aviso novamente, ainda receberá o aviso para o bloco que estava dentro do bloco DISABLE_WARNING / ENABLE_WARNING. Para algumas versões do gcc, funciona, para outras, não.
fonte
Substitua "-Formato" pelo nome do seu sinalizador de aviso.
No AFAIK, não há como usar a semântica push / pop para esta opção.
fonte
Eu tive o mesmo problema com bibliotecas externas como cabeçalhos ROS. Eu gosto de usar as seguintes opções no CMakeLists.txt para uma compilação mais rigorosa:
Entretanto, fazer isso causa todos os tipos de erros pedantes nas bibliotecas incluídas externamente. A solução é desativar todos os avisos pedantes antes de incluir bibliotecas externas e reativar assim:
fonte
Eu sei que a pergunta é sobre o GCC, mas para pessoas que procuram como fazer isso em outros e / ou vários compiladores ...
TL; DR
Você pode dar uma olhada no Hedley , que é um cabeçalho C / C ++ de domínio público que escrevi, que faz muitas dessas coisas para você. Vou colocar uma seção rápida sobre como usar o Hedley para tudo isso no final deste post.
Desativando o aviso
#pragma warning (disable: …)
possui equivalentes na maioria dos compiladores:#pragma warning(disable:4996)
#pragma GCC diagnostic ignored "-W…"
onde as reticências são o nome do aviso; por exemplo ,#pragma GCC diagnostic ignored "-Wdeprecated-declarations
.#pragma clang diagnostic ignored "-W…"
. A sintaxe é basicamente a mesma que a do GCC, e muitos dos nomes de aviso são os mesmos (embora muitos não sejam).#pragma warning(disable:1478 1786)
.diag_suppress
pragma:#pragma diag_suppress 1215,1444
diag_suppress
pragma com a mesma sintaxe (mas com números de aviso diferentes!) Da IGP:pragma diag_suppress 1291,1718
error_messages
pragma. Irritantemente, os avisos são diferentes para os compiladores C e C ++. Ambos desabilitam basicamente os mesmos avisos:#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
#pragma error_messages(off,symdeprecated,symdeprecated2)
diag_suppress
como IGP e TI, mas a sintaxe é diferente. Alguns dos números de aviso são os mesmos, mas eu outros divergimos:#pragma diag_suppress=Pe1444,Pe1215
#pragma warn(disable:2241)
Para a maioria dos compiladores, geralmente é uma boa ideia verificar a versão do compilador antes de tentar desabilitá-la; caso contrário, você acabará acionando outro aviso. Por exemplo, o GCC 7 adicionou suporte ao
-Wimplicit-fallthrough
aviso, portanto, se você se importa com o GCC antes do 7, deve fazer algo comoPara clang e compiladores baseados em clang, como nas versões mais recentes do XL C / C ++ e armclang, você pode verificar se o compilador conhece um aviso específico usando a
__has_warning()
macro.Claro que você também precisa verificar se a
__has_warning()
macro existe:Você pode ficar tentado a fazer algo como
Então você pode usar
__has_warning
um pouco mais facilmente. Clang até sugere algo semelhante para a__has_builtin()
macro em seu manual. Não faça isso . Outro código pode procurar__has_warning
e recorrer à verificação de versões do compilador, se não existir, e se você definir,__has_warning
quebrará o código. A maneira correta de fazer isso é criar uma macro no seu espaço para nome. Por exemplo:Então você pode fazer coisas como
Empurrando e estourando
Muitos compiladores também oferecem suporte a uma maneira de enviar e enviar avisos para uma pilha. Por exemplo, isso desativará um aviso no GCC para uma linha de código e retornará ao estado anterior:
É claro que não há muito acordo entre os compiladores sobre a sintaxe:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
#pragma clang diagnostic push
/#pragma diagnostic pop
#pragma warning(push)
/#pragma warning(pop)
#pragma warning(push)
/#pragma warning(pop)
#pragma push
/#pragma pop
#pragma diag_push
/#pragma diag_pop
#pragma warning(push)
/#pragma warning(pop)
Se a memória serve, para algumas versões muito antigas do GCC (como 3.x, IIRC), os pragmas push / pop precisavam estar fora da função.
Escondendo os detalhes sangrentos
Para a maioria dos compiladores, é possível ocultar a lógica por trás das macros usando
_Pragma
, introduzida no C99. Mesmo no modo não C99, a maioria dos compiladores suporta_Pragma
; a grande exceção é o MSVC, que possui sua própria__pragma
palavra-chave com uma sintaxe diferente. O padrão_Pragma
usa uma string, a versão da Microsoft não:É aproximadamente equivalente, uma vez pré-processado, a
Isso nos permite criar macros para escrever código como
E esconda todas as verificações feias das versões nas definições de macro.
O caminho mais fácil: Hedley
Agora que você entende a mecânica de como fazer coisas assim de maneira portável, mantendo seu código limpo, entende o que um dos meus projetos, Hedley faz. Em vez de vasculhar toneladas de documentação e / ou instalar o maior número possível de compiladores para testar, basta incluir o Hedley (é um cabeçalho C / C ++ de domínio público) e pronto. Por exemplo:
Desabilitará o aviso sobre a chamada de uma função obsoleta no GCC, clang, ICC, PGI, MSVC, TI, IAR, ODS, Pelles e possivelmente outras (provavelmente não me incomodarei em atualizar esta resposta ao atualizar o Hedley). E, nos compiladores que não são conhecidos por funcionar, as macros serão pré-processadas para nada, portanto, seu código continuará funcionando com qualquer compilador. É claro que esse
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
não é o único aviso que Hedley conhece, nem os avisos desabilitadores que Hedley pode fazer, mas espero que você entenda.fonte
Em vez de silenciar os avisos, o estilo gcc geralmente usa construções C padrão ou a
__attribute__
extensão para informar ao compilador mais sobre sua intenção. Por exemplo, o aviso sobre a atribuição usada como condição é suprimido colocando a atribuição entre parênteses, ou seja, emif ((p=malloc(cnt)))
vez deif (p=malloc(cnt))
. Os avisos sobre argumentos de funções não utilizadas podem ser suprimidos por alguns itens estranhos dos quais__attribute__
nunca me lembro, ou por auto-designações, etc. Mas geralmente prefiro desabilitar globalmente qualquer opção de aviso que gere avisos para coisas que ocorrerão no código correto.fonte
if ((p=malloc(cnt)) != NULL) ...
que é isso que o compilador está fazendo nos bastidores.Para quem encontrou esta página procurando uma maneira de fazer isso no IAR, tente o seguinte:
Consulte http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472m/chr1359124244797.html para obter referência.
fonte