Pergunta

muitas vezes eu achar que a seção de cabeçalhos de um arquivo ficar maior e maior o tempo todo, mas ele nunca fica menor. Ao longo da vida de um aulas de arquivo de origem pode ter movido e foi refeito e é muito possível que haja um #includes muito poucos que não precisa estar lá e mais. Deixando-os lá somente prolongar o tempo de compilação e adiciona as dependências de compilação desnecessárias. Tentando descobrir que ainda são necessários pode ser bastante tedioso.

Existe algum tipo de ferramenta que pode detectar diretivas #include supérfluos e sugerir quais eu possa remover com segurança?
Does Lint fazer isso talvez?

Foi útil?

Solução

Não é automático, mas doxygen irá produzir diagramas de dependência para arquivos #included. Você terá que passar por eles visualmente, mas eles podem ser muito útil para obter uma imagem do que está usando o quê.

Outras dicas

cppclean do Google (links para: download , documentação ) pode encontrar várias categorias de problemas C ++, e pode agora encontrar #includes supérfluas.

Há também uma ferramenta baseada em Clang, incluem-que- you-use , que pode fazer isso. incluem-que-você-uso pode até mesmo sugerir declarações para a frente (assim você não tem que # incluir tanto) e, opcionalmente, limpar seus #includes para você.

As versões atuais do Eclipse CDT também têm essa funcionalidade construído em: indo no menu Fonte e clicando organizar inclui vai alfabetizar seus # incluir de, adicione quaisquer cabeçalhos que Eclipse pensa que você está usando, sem incluí-los diretamente, e comentários qualquer cabeçalhos que ele não acha que precisa. Este recurso não é 100% confiável, no entanto.

Também check out incluem-what-you-use , que resolve um problema semelhante.

O problema com a detecção supérfluo inclui é que ele não pode ser apenas um verificador de tipos de dependência. A supérfluo incluir é um arquivo que fornece nada de valor para a compilação e não altera outro item que outros arquivos dependem. Há muitas maneiras de um arquivo de cabeçalho podem alterar uma compilação, dizer, definindo uma constante, redefinindo e / ou exclusão de um macro usado, adicionando um namespace que altera a pesquisa de um nome de alguma forma para baixo da linha. A fim de detectar itens como o namespace que você precisa muito mais do que um pré-processador, você na verdade quase precisa de um compilador completo.

Lint é mais de um verificador de estilo e, certamente, não terá essa capacidade plena.

Eu acho que você vai encontrar a única maneira de detectar um supérfluo incluir é remover, de compilação e suites executados.

Eu pensei que PCLint faria isso, mas tem sido há alguns anos desde Eu olhei para ele. Você pode verificá-la.

Eu olhei para este blog eo autor conversamos um pouco sobre como configurar PCLint para encontrar não utilizado inclui. Pode valer a pena dar uma olhada.

O CScout navegador refatoração pode detectar supérfluo incluir diretivas em C (infelizmente não C ++) de código. Você pode encontrar uma descrição de como ele funciona em este artigo de jornal .

Você pode escrever um script rápido que apaga uma única diretiva #include, compila os projectos, e registra o nome na # include eo arquivo foi removido do no caso de que nenhum erro de compilação ocorreu.

Deixe-o funcionar durante a noite, e no dia seguinte você vai ter um 100% lista correta de incluir arquivos que você pode remover.

brute-force Às vezes simplesmente funciona: -)


Editar: e às vezes não :-). Aqui está um pouco de informação a partir dos comentários:

  1. Às vezes, você pode remover dois arquivos de cabeçalho separadamente, mas não os dois juntos. A solução é remover os arquivos de cabeçalho durante a corrida e não trazê-los de volta. Isto vai encontrar uma lista de arquivos que você pode remover com segurança, embora possa uma solução com mais arquivos para remover que este algoritmo não vai encontrar. (É uma busca gananciosa no espaço de incluir arquivos de remover. Ele só vai encontrar um máximo local)
  2. Pode haver mudanças sutis no comportamento se você tem alguns macros redefiniu de forma diferente dependendo de alguns #ifdefs. Penso que estes são casos muito raros, e os testes de unidade que são parte da construção deve pegar estas mudanças.

Desculpe a (re) post aqui, as pessoas muitas vezes não se expandem comentários.

Verifique o meu comentário a crashmstr, FlexeLint / PC-Lint vai fazer isso por você. mensagem informativa 766. Seção 11.8.1 do meu manual (versão 8.0) discute isso.

Além disso, e isso é importante, manter a iteração até que a mensagem vai embora . Em outras palavras, após a remoção de cabeçalhos não utilizadas, fiapos re-run, mais arquivos de cabeçalho poderia ter se tornado "desnecessários" uma vez que você remover alguns cabeçalhos desnecessários. (Isso pode parecer bobagem, lê-lo lentamente e analisá-lo, faz sentido.)

Eu nunca encontrei uma ferramenta de pleno direito que realiza o que você está pedindo. A coisa mais próxima que eu usei é IncludeManager , que traça sua árvore inclusão de cabeçalho para que você possa identificar visualmente coisas como cabeçalhos incluídos em um único arquivo e inclusões de cabeçalho circulares.

Se você estiver usando Eclipse CDT você pode tentar http://includator.com que é gratuito para beta testers (pelo momento da redação deste texto) e remove automaticamente #includes supérfluos ou acrescenta que faltam. Para aqueles usuários que têm FlexeLint ou PC-Lint e estão usando Elicpse CDT, http://linticator.com pode ser uma opção (também livre para o teste beta). Enquanto ele usa a análise de Lint, ele fornece soluções rápidas para remover automaticamente as instruções # include supérfluo.

Eu tentei usar Flexelint (a versão UNIX do PC-Lint) e tiveram resultados um tanto contraditórios. Isto é provavelmente porque eu estou trabalhando em um muito grande e complicado base de código. Eu recomendo examinando cuidadosamente cada arquivo que é relatado como não utilizado.

A principal preocupação é falsos positivos. Inclui múltiplos do mesmo cabeçalho são relatados como um cabeçalho desnecessários. Isso é ruim desde Flexelint não lhe diz o que alinham o cabeçalho está incluído na ou onde ele foi incluído antes.

Uma das maneiras ferramentas automatizadas pode obter esta errado:

Em A.hpp:

class A { 
  // ...
};

Em B.hpp:

#include "A.hpp

class B {
    public:
        A foo;
};

Em C.cpp:

#include "C.hpp"  

#include "B.hpp"  // <-- Unneeded, but lint reports it as needed
#include "A.hpp"  // <-- Needed, but lint reports it as unneeded

Se você seguir cegamente as mensagens Flexelint você vai estragar suas dependências # include. Há casos mais patológicos, mas basicamente você está indo para necessidade de inspecionar os cabeçalhos-se para melhores resultados.

Eu recomendo altamente este artigo sobre estrutura física e C ++ dos Jogos de blog de dentro. Eles recomendam uma abordagem abrangente para limpar a bagunça #include:

Diretrizes

Aqui está um conjunto destilado de diretrizes de livro Lakos’ que minimizam o número de dependências físicas entre arquivos. Eu tenho usado eles há anos e sempre fui muito feliz com os resultados.

  1. Cada arquivo CPP inclui seu próprio arquivo de cabeçalho em primeiro lugar. [Snip]
  2. Um arquivo de cabeçalho deve incluir todos os arquivos necessários no cabeçalho para analisá-lo. [Snip]
  3. Um arquivo de cabeçalho deve ter o número mínimo de arquivos de cabeçalho necessários para analisá-lo. [Snip]

Este artigo explica uma técnica de #include remoção usando a análise de Doxygen. Isso é apenas um script Perl, por isso é bastante fácil de usar.

Há uma ferramenta livre Incluir arquivo dependências Watcher que pode ser integrado no estúdio visual. Ele mostra #includes supérfluos em vermelho.

Talvez um pouco tarde, mas uma vez eu encontrei um script WebKit perl que fez exatamente o que queria. Ele vai precisar de algum adaptando Eu acredito (não estou bem versado em perl), mas deve fazer o truque:

http : //trac.webkit.org/browser/branches/old/safari-3-2-branch/WebKitTools/Scripts/find-extra-includes

(este é um ramo de idade, porque tronco não tem o arquivo anymore)

Há dois tipos de arquivos # include supérfluos:

  1. Um arquivo de cabeçalho, na verdade, não é necessário por o módulo (.c, .cpp) em tudo
  2. Um arquivo de cabeçalho é necessário pelo módulo mas ser incluído mais de uma vez, direta ou indiretamente.

Há 2 maneiras em minha experiência que funciona bem para detectá-lo:

  • gcc -H ou cl.exe / showincludes (problema resolve 2)

    No mundo real, você pode exportar CFLAGS = -H antes de marca, se não substituir todos do Makefile opções CFLAGS. Ou como eu costumava, você pode criar um cc / g ++ wrapper para adicionar -H opções à força a cada invocação de $ (CC) e $ (CXX). e preceder a diretório do wrapper para $ PATH variável, então a sua marca serão todos usa-lo invólucro de comando em vez. Do Claro que o seu invólucro deve invocar o compilador gcc real. Isso engana necessidade de mudança se seus usos Makefile gcc directamente. em vez de $ (CC) ou $ (CXX) ou por regras implícitas.

    Você também pode compilar um único arquivo por ajustes com a linha de comando. Mas se você quiser cabeçalhos limpas para todo o projecto. Você pode capturar toda a saída por:

    make clean

    make 2> & 1 | tee result.txt

  • PC-Lint / FlexeLint (problema resolve ambos 1 e 2)

    Faça adicionar se as opções + e766, este aviso é sobre: arquivos de cabeçalho não utilizado.

    pclint / Flint -vf ...

    Isto fará com que arquivos de cabeçalho incluídos saída pclint, arquivos de cabeçalho aninhadas será recuado de forma adequada.

Para terminar esta discussão: o c ++ pré-processador é turing completa. É uma propriedade semântica, se um incluem é supérfluo. Assim, resulta do teorema de Rice que é indecidível se um incluem é supérfluo ou não. Não pode haver um programa, que (sempre corretamente) detecta se um include é supérfluo.

Aqui é um simples força bruta maneira de identificar cabeçalho supérfluo inclui . Não é perfeito, mas elimina inclui o "óbvio" desnecessário. Livrar-se dessas vai um longo caminho para limpar o código.

roteiros podem ser acessados ??diretamente no GitHub.

PC Lint de Gimpel Software poderá informar quando um arquivo de inclusão foi incluído mais de uma vez em uma unidade de compilação , mas não pode encontrar incluir arquivos que não são necessários na maneira que você está procurando.

Editar: É possível. Ver resposta

CLION , o C / C ++ IDE de JetBrains, detecta redundante inclui out-of-the -caixa. Estes são acinzentado no editor, mas também há funções para otimizar inclui no arquivo atual ou projeto inteiro .

Eu descobri que você paga para essa funcionalidade embora; CLION leva um tempo para digitalizar e analisar o seu projeto quando carregada pela primeira vez.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top