C / C++: wykrywanie zbędnych # includes?

Często stwierdzam, że sekcja nagłówków pliku staje się coraz większa, ale nigdy nie staje się mniejsza. Przez cały okres istnienia plików źródłowych klasy mogły się przenosić i być refakturowane i jest bardzo możliwe, że jest sporo #includes, które nie muszą już tam być. Pozostawienie ich tam tylko wydłuża czas kompilacji i dodaje niepotrzebne zależności kompilacji. Próbowanie dowiedzieć się, które są nadal potrzebne, może być dość żmudne.

Czy Jest jakieś narzędzie które wykrywają zbędne dyrektywy # include I sugerują, które z nich mogę bezpiecznie usunąć?
Czy lint może to robi?

Author: shoosh, 2009-03-05

19 answers

To nie jest automatyczne, ale Doxygen stworzy diagramy zależności dla #dołączonych plików. Będziesz musiał przejść przez nich wizualnie, ale mogą być bardzo przydatne do uzyskania obrazu tego, co jest za pomocą czego.

 39
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 14:13:57

Cppclean Google (linki do: Pobierz, documentation ) może znaleźć kilka kategorii problemów C++, a teraz może znaleźć zbędne # includes.

Istnieje również narzędzie oparte na Clang, include-what-you-use , które może to zrobić. include-what-you-use może nawet sugerować deklaracje forward (więc nie musisz #zawierać tak dużo) i opcjonalnie wyczyścić swoje # includes za Ciebie.

Obecne wersje Eclipse CDT również posiadają tę funkcjonalność wbudowany: wchodząc pod menu Źródła i klikając zorganizuj Zawiera będzie alfabetyzować swoje #include ' S, dodać nagłówki, które Eclipse myśli, że używasz bez bezpośredniego włączania ich, i komentuje wszystkie nagłówki, które nie są potrzebne. Ta funkcja nie jest jednak w 100% niezawodna.

 140
Author: Josh Kelley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-09 15:01:40

Sprawdź również include-what-you-use , co rozwiązuje podobny problem.

 53
Author: Tzafrir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-04 13:03:00

Problem z wykrywaniem zbędnych includes polega na tym, że nie może to być tylko sprawdzanie zależności typu. Zbyteczny include to plik, który nie dostarcza żadnej wartości kompilacji i nie zmienia innego elementu, od którego zależą inne pliki. Istnieje wiele sposobów, w jaki plik nagłówkowy może zmienić kompilację, np. definiując stałą, przedefiniowując i / lub usuwając używane makro, dodając przestrzeń nazw, która zmienia wyszukiwanie nazwy w dół linii. W celu wykrycia takich elementów jak przestrzeń nazw potrzebujesz znacznie więcej niż preprocesora, w rzeczywistości prawie potrzebujesz pełnego kompilatora.

Lint jest bardziej kontrolerem stylu i na pewno nie będzie miał tej pełnej możliwości.

Myślę, że jedynym sposobem wykrycia zbędnego include jest usunięcie, skompilowanie i uruchomienie pakietów.

 23
Author: JaredPar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 15:02:59

Myślałem, że PCLint zrobi to, ale minęło kilka lat, odkąd na to patrzyłem. Możesz to sprawdzić.

Spojrzałem na Ten blog i autor mówił trochę o konfiguracji Pclinta, aby znaleźć nieużywane includes. Może warto zajrzeć.

 15
Author: itsmatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 14:06:19

Przeglądarka cscout potrafi wykryć zbędne dyrektywy include w kodzie C (niestety nie C++). Opis tego, jak to działa, można znaleźć w w tym artykule w czasopiśmie.

 7
Author: Diomidis Spinellis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 14:53:07

Możesz napisać szybki skrypt, który usuwa pojedynczą dyrektywę # include, kompiluje projekty i rejestruje nazwę w #include I Plik, z którego został usunięty w przypadku, gdy nie wystąpiły błędy kompilacji.

Pozwól mu działać w nocy, a następnego dnia będziesz miał 100% poprawną listę plików nagłówkowych, które możesz usunąć.

Czasami brute-force po prostu działa : -)


Edit: a czasem nie: -). Oto trochę informacji z komentarze:

  1. czasami można usunąć dwa pliki nagłówkowe osobno, ale nie oba razem. Rozwiązaniem jest usunięcie plików nagłówkowych podczas uruchamiania i nie przywracanie ich z powrotem. Znajdzie to listę plików, które można bezpiecznie usunąć, chociaż może istnieć rozwiązanie z większą liczbą plików do usunięcia, których ten algorytm nie znajdzie. (jest to chciwe przeszukiwanie przestrzeni plików nagłówkowych do usunięcia. Znajdzie tylko lokalne maksimum)
  2. mogą wystąpić subtelne zmiany w zachowaniu, jeśli masz niektóre makra redefiniowały się inaczej w zależności od niektórych #ifdefs. Myślę, że są to bardzo rzadkie przypadki, a testy jednostkowe, które są częścią kompilacji, powinny wychwycić te zmiany.
 5
Author: Gilad Naor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 14:45:42

Sorry za (re-)post tutaj, ludzie często nie rozszerzają komentarzy.

Sprawdź mój komentarz do crashmstr, FlexeLint / PC-Lint zrobi to za Ciebie. Wiadomość informacyjna 766. Sekcja 11.8.1 mojego podręcznika (wersja 8.0) omawia to.

Również, i to jest ważne, powtarzaj, aż wiadomość zniknie . Innymi słowy, po usunięciu nieużywanych nagłówków, ponownie uruchom lint, więcej plików nagłówkowych może stać się" niepotrzebnych " po usunięciu niektórych niepotrzebnych nagłówków. (To może brzmieć głupie, Czytaj powoli i analizuj, to ma sens.)

 5
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 19:02:11

Nigdy nie znalazłem pełnowartościowego narzędzia, które spełni to, o co prosisz. Najbliższą rzeczą, której użyłem, jest IncludeManager , który wykresuje drzewo włączenia nagłówka, dzięki czemu możesz wizualnie dostrzec rzeczy takie jak nagłówki zawarte tylko w jednym pliku i okrągłe wtrącenia nagłówka.

 5
Author: Dan Olson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-10 10:22:46

Jeśli używasz Eclipse CDT możesz spróbować http://includator.com który jest darmowy dla beta testerów (w momencie pisania tego tekstu) i automatycznie usuwa zbędne # zawiera lub dodaje brakujące. Dla tych użytkowników, którzy mają FlexeLint lub PC-Lint i używają Elicpse CDT, http://linticator.com może być opcja (również darmowa do beta testów). Podczas gdy używa analizy Linta, zapewnia szybkie poprawki do automatycznego usuwania zbędnych instrukcji # include.

 4
Author: PeterSom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-01 12:52:20

Próbowałem używać Flexelint (uniksowej wersji PC-Lint) i miałem nieco mieszane wyniki. Jest to prawdopodobnie dlatego, że pracuję na bardzo dużej i knotty kod bazy. Zalecam dokładne zbadanie każdego pliku, który jest zgłaszany jako nieużywany.

Głównym zmartwieniem są fałszywe alarmy. Wiele nagłówków tego samego nagłówka jest zgłaszanych jako niepotrzebny nagłówek. Jest to złe, ponieważ Flexelint nie mówi, w jakiej linii nagłówek jest dołączony lub gdzie był wcześniej dołączony.

Jeden z sposoby, w jaki zautomatyzowane narzędzia mogą to źle zrobić:

W A. hpp:

class A { 
  // ...
};

W B. hpp:

#include "A.hpp

class B {
    public:
        A foo;
};

W 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

Jeśli ślepo podążasz za wiadomościami z Flexelint, rozwalisz swoje zależności # include. Jest więcej przypadków patologicznych, ale zasadniczo będziesz musiał sprawdzić nagłówki samodzielnie, aby uzyskać najlepsze wyniki.

Gorąco polecam ten artykuł o Physical Structure i C++ z bloga Games from within. Polecają kompleksowe podejście do sprzątania bałaganu # include:

Wytyczne

Oto wydestylowany zestaw wytycznych z książki Lakosa, które minimalizują liczbę fizycznych zależności między plikami. Używam ich od lat i zawsze byłem bardzo zadowolony z efektów.

  1. każdy plik cpp zawiera najpierw własny plik nagłówka. [snip]
  2. plik nagłówkowy musi zawierać wszystkie pliki nagłówkowe niezbędne do jego analizy. [snip]
  3. A plik nagłówkowy powinien mieć minimalną liczbę plików nagłówkowych niezbędnych do jego przetworzenia. [snip]
 2
Author: Ben Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-05 22:07:26

Ten artykuł wyjaśnia technikę usuwania #include za pomocą parsowania Doxygen. To tylko skrypt Perla, więc jest dość łatwy w użyciu.

 2
Author: Steve Gury,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-10 10:14:15

Istnieje darmowe narzędzie Include File Dependencies Watcher , które można zintegrować z visual studio. Pokazuje zbędne # zawiera na Czerwono.

 2
Author: Vladimir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-06 20:34:30

Na zakończenie tej dyskusji: preprocesor c++ jest kompletny. Jest to właściwość semantyczna, bez względu na to, czy include jest zbędny. Stąd wynika z twierdzenia Rice ' a, że nie można zdecydować, czy włączenie jest zbędne, czy nie. Nie może istnieć program, który (zawsze poprawnie) wykrywa, czy include jest zbędny.

 2
Author: Algoman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-07 16:00:28

Może trochę za późno, ale kiedyś znalazłem skrypt WebKit perl, który zrobił to, co chciałeś. Będzie potrzebował trochę adaptacji, jak sądzę (nie znam się dobrze na perlu), ale powinno zadziałać:

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

(jest to stara gałąź, ponieważ trunk nie ma już pliku)

 1
Author: rubenvb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-30 14:47:41

Istnieją dwa rodzaje zbędnych plików nagłówkowych:

  1. plik nagłówkowy właściwie nie potrzebny przez moduł (.c, .cpp) w ogóle
  2. plik nagłówkowy jest potrzebny przez moduł ale bycie włączonym więcej niż raz, bezpośrednio lub pośrednio.

Z mojego doświadczenia wynika, że są 2 sposoby na wykrycie tego:

  • Gcc-H lub cl.exe / showincludes (resolve problem 2)

    In real world, możesz wyeksportować CFLAGS= - H przed wykonaniem, jeśli cały Makefile nie jest override Opcje CFLAGS. Albo jak kiedyś, ty można utworzyć wrapper cc / g++, aby dodać -H opcje do każdego wywołania z $(CC) i $(CXX). and prepend the katalog wrappera do $PATH zmienna, wtedy Twoja marka będzie zamiast tego używa polecenia owijania. Z oczywiście owijarka powinna wywoływać prawdziwy kompilator gcc. Ta sztuczka musisz zmienić, jeśli twój Makefile używa gcc bezpośrednio. zamiast $(CC) lub $(CXX) lub według dorozumianych reguł.

    Możesz również skompilować pojedynczy plik, klikając polecenie Kolejka Ale jeśli chcesz wyczyścić nagłówki dla całego projektu. Możesz przechwycić wszystkie dane wyjściowe przez:

    Make clean

    Make 2 > &1 | tee result.txt

  • PC-Lint / FlexeLint(Rozwiąż problem zarówno 1 i 2)

    Upewnij się, że dodałeś opcje + e766, to Ostrzeżenie jest o: nieużywane pliki nagłówkowe.

    Pclint / flint-vf ...

    Spowoduje to, że wyjście pclint zawiera pliki nagłówkowe, zagnieżdżone pliki nagłówkowe będą odpowiednio wcięte.

 1
Author: zhaorufei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-20 00:27:17

Oto prosty brutalny sposób identyfikacji zbędnego nagłówka zawiera. Nie jest idealny, ale eliminuje" oczywiste " niepotrzebne obejmuje. Pozbycie się ich zajmuje dużo czasu w czyszczeniu kodu.

Skrypty są dostępne bezpośrednio na Githubie.

 1
Author: ap-osd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-14 10:24:58

Oprogramowanie Gimpel PC Lint może raportować, kiedy plik nagłówka został dołączony więcej niż raz do jednostki kompilacji , ale nie może znaleźć plików nagłówka, które nie są potrzebne w sposób, którego szukasz.

Edit: może. Zobacz odpowiedź itsmatt

 0
Author: crashmstr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:56

CLion , C / C++ IDE z JetBrains, wykrywa redundantne includes out-of-the-box. Są one wyszarzone w edytorze, ale istnieją również funkcje do optymalizacji zawartości w bieżącym pliku lub w całym projekcie.

Odkryłem, że płacisz za tę funkcjonalność; CLion zajmuje trochę czasu, aby skanować i analizować swój projekt po pierwszym załadowaniu.

 0
Author: congusbongus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-06 23:53:42