Examinei e encontrei o conjunto mínimo de inclusões que deveria receber o nível máximo de aviso. Em seguida, removi dessa lista o conjunto de avisos que, na verdade, não indicam que algo de ruim está acontecendo, ou então há muitos falsos positivos para serem usados em uma compilação real. Comentei por que todos os que excluí foram excluídos. Este é o meu conjunto final de avisos sugeridos:
-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused
Avisos questionáveis presentes:
Incluo -Wno-unused
porque geralmente tenho variáveis que sei que usarei mais tarde, mas ainda não tenho a funcionalidade escrita. A remoção de avisos sobre isso me permite escrever no meu estilo preferido de adiar ocasionalmente a implementação das coisas. É útil desativá-lo de vez em quando para garantir que nada escorregue pelas rachaduras.
-Wdisabled-optimization
parece uma forte configuração de preferência do usuário. Acabei de adicionar este à minha compilação (apenas para compilações otimizadas por razões óbvias) e ele não apareceu nada, por isso não parece ser um aviso especialmente falador, pelo menos pela maneira como codifico. Eu o incluo (mesmo que o código que aciona esse aviso não esteja necessariamente errado) porque acredito em trabalhar com minhas ferramentas em vez de contra elas. Se o gcc está me dizendo que não pode otimizar o código da maneira como o escrevi, então devo reescrevê-lo. Suspeito que o código que aciona esse aviso possa se beneficiar de ser mais modular, independentemente, portanto, embora o código não esteja tecnicamente errado (provavelmente), estilisticamente é provável.
-Wfloat-equal
alerta para comparações de igualdade seguras (em particular, comparação com um valor não calculado de -1). Um exemplo no meu código em que eu uso isso é que eu tenho um vetor de float. Eu passo por esse vetor e há alguns elementos que ainda não posso avaliar o que deveriam ser, então os defino como -1.0f (já que meu problema usa apenas números positivos, -1 está fora do domínio). Mais tarde, passo a atualizar os valores -1.0f. Não se presta facilmente a um método de operação diferente. Eu suspeito que a maioria das pessoas não tenha esse problema, e a comparação de um número exato em ponto flutuante provavelmente é um erro, por isso estou incluindo-o na lista padrão.
-Wold-style-cast
tem muitos falsos positivos no código da biblioteca que estou usando. Em particular, a família de funções htonl usada nas redes, bem como a implementação de criptografia Rijndael (AES) que estou usando, tem moldes no estilo antigo que me alertam. Pretendo substituir os dois, mas não tenho certeza se há mais alguma coisa no meu código sobre a qual ele reclamará. A maioria dos usuários provavelmente deve ter isso por padrão, no entanto.
-Wsign-conversion
foi difícil (e quase não entrou na lista). Ativá-lo no meu código gerou uma enorme quantidade de avisos (mais de 100). Quase todos eles eram inocentes. No entanto, tomei o cuidado de usar números inteiros assinados sempre que não tivesse certeza, embora, para meu domínio de problema específico, normalmente recebesse um ligeiro aumento de eficiência usando valores não assinados devido à grande quantidade de divisão de números inteiros que faço. Eu sacrifiquei essa eficiência porque estava preocupado em promover acidentalmente um número inteiro assinado para um não assinado e depois dividi-lo (o que não é seguro, ao contrário da adição, subtração e multiplicação). Ativar esse aviso me permitiu alterar com segurança a maioria das minhas variáveis para tipos não assinados e adicionar algumas transmissões em outros lugares. Atualmente, é um pouco difícil de usar, porque o aviso não é tão inteligente. Por exemplo, se você fizerunsigned short + (integral
constant expression)
, esse resultado é implicitamente promovido para int. Em seguida, ele avisa sobre um possível problema de sinal se você atribuir esse valor a
unsigned
ou unsigned short
, mesmo que seja seguro. Esse é definitivamente o aviso mais opcional para quase todos os usuários.
-Wsign-promo
: veja -Wsign-conversion
.
-Wswitch-default
parece inútil (você nem sempre quer um caso padrão se tiver enumerado explicitamente todas as possibilidades). No entanto, ativar esse aviso pode aplicar algo que provavelmente é uma boa ideia. Nos casos em que você deseja explicitamente ignorar tudo, exceto as possibilidades listadas (mas outros números são possíveis), insiradefault: break;
para torná-lo explícito. Se você enumerar explicitamente todas as possibilidades, ativar esse aviso ajudará a garantir algo como assert (false) para garantir que você realmente cobriu todas as opções possíveis. Ele permite que você seja explícito em qual é o domínio do seu problema e o imponha programaticamente. No entanto, você terá que ter cuidado em apenas afirmar (false) em qualquer lugar. É melhor do que não fazer nada com o caso padrão, mas, como de costume com assert, ele não funcionará nas versões do release. Em outras palavras, você não pode confiar nele para validar os números obtidos de, digamos, uma conexão de rede ou um banco de dados sobre o qual você não tem controle absoluto. Exceções ou retorno antecipado são a melhor maneira de lidar com isso (mas ainda exigem que você tenha um caso padrão!).
-Werror
é importante para mim. Ao compilar grandes quantidades de código em uma compilação multithread com vários destinos, é fácil passar um aviso. Transformar avisos em erros garante que eu os observe.
Depois, há um conjunto de avisos que não estão incluídos na lista acima porque eu não achei que fossem úteis. Estes são os avisos e meus comentários sobre por que não os incluo na lista padrão:
Avisos ausentes:
-Wabi
não é necessário porque não estou combinando binários de diferentes compiladores. Tentei compilar com ele de qualquer maneira, e não foi acionado, por isso não parece desnecessariamente detalhado.
-Waggregate-return
não é algo que eu considere um erro. Por exemplo, ele é acionado ao usar um loop for baseado em intervalo em um vetor de classes. A otimização do valor de retorno deve cuidar de quaisquer efeitos negativos disso.
-Wconversion
aciona esse código: short n = 0; n += 2;
a conversão implícita em int causa um aviso quando é convertida novamente em seu tipo de destino.
-Weffc++
inclui um aviso se todos os membros dos dados não forem inicializados na lista de inicializadores. Intencionalmente não faço isso em muitos casos, portanto o conjunto de avisos é muito confuso para ser útil. É útil ativar de vez em quando e procurar outros avisos (como destruidores não virtuais de classes base). Isso seria mais útil como uma coleção de avisos (como -Wall
) em vez de um único aviso por si só.
-Winline
está ausente porque eu não uso a palavra-chave inline para fins de otimização, apenas para definir funções inline nos cabeçalhos. Não me importo se o otimizador realmente o alinha. Esse aviso também se queixa se não conseguir incorporar uma função declarada em um corpo de classe (como um destruidor virtual vazio).
-Winvalid-pch
está ausente porque eu não uso cabeçalhos pré-compilados.
-Wmissing-format-attribute
não é usado porque eu não uso extensões gnu. Mesmo para -Wsuggest-attribute
e vários outros
Potencialmente notável por sua ausência é -Wno-long-long
, da qual eu não preciso. Eu compilo com -std=c++0x
( -std=c++11
no GCC 4.7), que inclui long long
tipos inteiros. Os que estão presos no C ++ 98 / C ++ 03 podem considerar adicionar essa exclusão da lista de avisos.
-Wnormalized=nfc
já é a opção padrão e parece ser a melhor.
-Wpadded
é ativado ocasionalmente para otimizar o layout das classes, mas não é ativado porque nem todas as classes têm elementos suficientes para remover o preenchimento no final. Em teoria, eu poderia obter algumas variáveis extras para 'free', mas não vale a pena o esforço extra de manter isso (se o tamanho da minha classe mudar, não é fácil remover essas variáveis anteriormente livres).
-Wstack-protector
não é usado porque eu não uso -fstack-protector
-Wstrict-aliasing=3
está ativado -Wall
e é o mais preciso, mas parece que os níveis 1 e 2 dão mais avisos. Em teoria, um nível mais baixo é um aviso "mais forte", mas custa mais falsos positivos. Meu próprio código de teste compilado de forma limpa em todos os três níveis.
-Wswitch-enum
Não é um comportamento que eu quero. Não quero lidar com todas as instruções de switch explicitamente. Seria útil se o idioma tivesse algum mecanismo para ativar isso em instruções de chave especificadas (para garantir que futuras alterações na enum sejam tratadas em todos os lugares que elas precisam estar), mas é um exagero para uma configuração de "tudo ou nada".
-Wunsafe-loop-optimizations
causa muitos avisos espúrios. Pode ser útil aplicar este periodicamente e verificar manualmente os resultados. Como exemplo, ele gerou esse aviso no meu código quando fiz um loop sobre todos os elementos em um vetor para aplicar um conjunto de funções a eles (usando o loop for baseado em intervalo). Também é um aviso para o construtor de uma matriz const de const std :: string (onde não há loop no código do usuário).
-Wzero-as-null-pointer-constant
e -Wuseless-cast
são apenas avisos do GCC-4.7, que adicionarei quando passar para o GCC 4.7.
Arquivei alguns relatórios de bugs / solicitações de aprimoramento no gcc como resultado de algumas dessas pesquisas. Espero que, eventualmente, eu possa adicionar mais avisos da lista "não incluir" na lista "incluir" . Esta lista inclui todos os avisos mencionados neste tópico (além de alguns extras). Muitos dos avisos não mencionados explicitamente nesta postagem estão incluídos como parte de outro aviso que menciono. Se alguém perceber completamente quaisquer avisos excluídos desta postagem, entre em contato.
edit: Parece que eu perdi vários (que eu adicionei agora). Na verdade, existe uma segunda página em http://gcc.gnu.org que está muito bem oculta. Opções gerais de aviso e opções C ++ (role para baixo até o final para obter avisos)
-Wall
) é uma-Wbloody_everything
bandeira :-)