Обнаружение лишних #include в C / C ++? - PullRequest
263 голосов
/ 05 марта 2009

Я часто нахожу, что секция заголовков файла все время увеличивается и увеличивается, но никогда не становится меньше. На протяжении всей жизни исходного файла классы могли перемещаться и подвергаться рефакторингу, и вполне возможно, что существует довольно много #includes, которые не должны быть там и больше. Оставив их там, можно только продлить время компиляции и добавить ненужные зависимости компиляции. Попытка выяснить, что еще нужно, может быть довольно утомительной.

Есть ли какой-нибудь инструмент, который может обнаружить лишние директивы #include и предложить, какие из них можно безопасно удалить?
Может ли это сделать Линт?

Ответы [ 19 ]

2 голосов
/ 06 марта 2009

Я пытался использовать Flexelint (Unix-версия PC-Lint) и получил несколько смешанные результаты. Это вероятно потому, что я работаю над очень большой и запутанной кодовой базой. Я рекомендую внимательно изучить каждый файл, который указан как неиспользованный.

Основное беспокойство - ложные срабатывания. Множественные включения одного и того же заголовка сообщаются как ненужный заголовок. Это плохо, поскольку Flexelint не сообщает вам, в какую строку включен заголовок или где он был включен ранее.

Один из способов, которым автоматизированные инструменты могут ошибиться:

В A.hpp:

class A { 
  // ...
};

В B.hpp:

#include "A.hpp

class B {
    public:
        A foo;
};

В 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

Если вы будете слепо следить за сообщениями от Flexelint, вы испортите свои зависимости #include. Есть больше патологических случаев, но в основном вам нужно будет самостоятельно проверить заголовки на предмет наилучших результатов.

Я настоятельно рекомендую эту статью о Физическая структура и C ++ из блога Games from inside. Они рекомендуют комплексный подход к устранению ошибок #include:

Руководство

Вот несколько рекомендаций из книги Лакоса, которые сводят к минимуму количество физических зависимостей между файлами. Я использую их годами и всегда был очень доволен результатами.

  1. Каждый файл cpp сначала включает свой собственный заголовочный файл. [Надрез]
  2. Файл заголовка должен включать все файлы заголовка, необходимые для его анализа. [Надрез]
  3. Файл заголовка должен иметь минимальное количество файлов заголовка, необходимых для его анализа. [Надрез]
2 голосов
/ 10 марта 2009

В этой статье объясняется техника удаления #include с помощью анализа Doxygen. Это всего лишь скрипт на Perl, поэтому его довольно просто использовать.

2 голосов
/ 06 января 2011

Существует бесплатный инструмент Включение средства отслеживания зависимостей файлов , который можно интегрировать в Visual Studio. Он показывает лишние #include красным.

1 голос
/ 14 апреля 2017

Вот простой грубый способ идентификации лишнего заголовка, включающий . Это не идеально, но устраняет «очевидные» ненужные включения. Избавление от них имеет большое значение для очистки кода.

Сценарии доступны непосредственно на GitHub.

1 голос
/ 07 апреля 2014

В завершение этого обсуждения: препроцессор c ++ завершен. Это семантическое свойство, является ли включение избыточным. Следовательно, из теоремы Райс следует, что неразрешимо, является ли включение избыточным или нет. НЕ МОЖЕТ быть программа, которая (всегда правильно) определяет, является ли включение лишним.

1 голос
/ 30 июня 2010

Возможно, немного поздно, но однажды я нашел Perl-скрипт WebKit, который делал именно то, что вы хотели. Я думаю, что потребуется некоторая адаптация (я не очень хорошо разбираюсь в Perl), но это должно сработать:

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

(это старая ветка, потому что в стволе больше нет файла)

1 голос
/ 14 декабря 2010

Существует два типа лишних файлов #include:

  1. Заголовочный файл на самом деле не нужен модуль (.c, .cpp) вообще
  2. Файл заголовка нужен модулю но включается более одного раза, прямо или косвенно.

В моем опыте есть 2 способа, которые хорошо подходят для его обнаружения:

  • gcc -H или cl.exe / showinclude (решить проблему 2)

    В реальном мире Вы можете экспортировать CFLAGS = -H, прежде чем делать, если все файлы Makefile не переопределены Варианты CFLAGS. Или, как я использовал, вы можно создать оболочку cc / g ++ для добавления -H варианты принудительно для каждого вызова $ (CC) и $ (CXX). и подготовить каталог оболочки в $ PATH переменная, тогда ваша марка будет все вместо этого использует вашу команду оболочки. из Конечно, ваша обертка должна вызывать настоящий компилятор gcc. Это хитрости нужно изменить, если ваш Makefile использует GCC напрямую. вместо $ (CC) или $ (CXX) или по подразумеваемым правилам.

    Вы также можете скомпилировать один файл, настроив его из командной строки. Но если вы хотите очистить заголовки для всего проекта. Вы можете захватить весь вывод:

    сделать чистым

    make 2> & 1 | результат. txt

  • PC-Lint / FlexeLint (решить проблему и 1 и 2)

    убедитесь, что добавили опции + e766, это предупреждение о: неиспользуемые заголовочные файлы.

    pclint / flint -vf ...

    Это приведет к выводу pclint включенных заголовочных файлов, вложенные заголовочные файлы будут соответствующим образом сдвинуты в отступ.

0 голосов
/ 07 апреля 2017

CLion , C / C ++ IDE от JetBrains, обнаруживает избыточные встроенные функции. Они недоступны в редакторе, но есть также функции для оптимизации включений в текущий файл или весь проект .

Я обнаружил, что вы платите за эту функцию; CLion требуется время для сканирования и анализа вашего проекта при первой загрузке.

0 голосов
/ 05 марта 2009

Gimpel Software's PC Lint может сообщить, когда включаемый файл был включен более одного раза в модуль компиляции , но он не может найти включаемые файлы, которые не нужны так, как вы ищем.

Редактировать: Может. См. ответ егоматта

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...