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

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

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

Ответы [ 19 ]

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

Google cppclean (ссылки на: загрузка , документация ) может найти несколько категорий проблем C ++, и теперь он может найти лишние # include.

Существует также инструмент на основе Clang, include-what-you-use , который может сделать это. include-what-you-use может даже предложить предварительные объявления (так что вам не нужно так много #include) и, при желании, очистить ваши #include для вас.

Текущие версии Eclipse CDT также имеют встроенную функциональность: перейдя в меню «Источник» и нажав «Организовать включения», вы расположите в алфавитном порядке ваши # включения, добавьте любые заголовки, которые, по вашему мнению, использует Eclipse, без непосредственного их включения и комментирует любые заголовки, которые вам не нужны. Однако эта функция не на 100% надежна.

58 голосов
/ 22 февраля 2011

Также проверьте include-what-you-use , который решает аналогичную проблему.

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

Это не автоматически, но doxygen создаст диаграммы зависимостей для файлов #included. Вам придется просматривать их визуально, но они могут быть очень полезны для получения изображения того, что и что использует.

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

Проблема с обнаружением лишних включений заключается в том, что это не может быть просто проверка зависимости типа. Избыточное включение - это файл, который ничего не представляет для компиляции , а не изменяет другой элемент, от которого зависят другие файлы. Существует много способов, которыми файл заголовка может изменить компиляцию, например, путем определения константы, переопределения и / или удаления использованного макроса, добавления пространства имен, которое изменяет поиск имени каким-либо образом вниз по строке. Чтобы обнаружить такие элементы, как пространство имен, вам нужно гораздо больше, чем препроцессор, фактически вам нужен почти полный компилятор.

Lint - это скорее средство проверки стиля, которое, безусловно, не будет обладать этой полной возможностью.

Я думаю, вы найдете единственный способ обнаружить лишнее включение - удалить, скомпилировать и запустить пакеты.

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

Я думал, что PCLint сделает это, но прошло несколько лет с тех пор, как я на это посмотрел. Вы можете проверить это.

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

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

Браузер рефакторинга CScout может обнаруживать лишние директивы include в коде C (к сожалению, не C ++). Вы можете найти описание того, как это работает, в этой журнальной статье.

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

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

Дайте ему поработать ночью, и на следующий день у вас будет 100% правильный список включаемых файлов, которые вы можете удалить.

Иногда перебор просто работает: -)


edit: и иногда это не так :-). Вот немного информации из комментариев:

  1. Иногда вы можете удалить два заголовочных файла по отдельности, но не оба вместе. Решение состоит в том, чтобы удалить заголовочные файлы во время выполнения, а не вернуть их обратно. Это позволит найти список файлов, которые вы можете безопасно удалить, хотя может быть решение с большим количеством файлов для удаления, которое не найдет этот алгоритм. (это жадный поиск по пространству включаемых файлов для удаления. Он найдет только локальный максимум)
  2. Возможны незначительные изменения в поведении, если некоторые макросы переопределяются по-разному в зависимости от некоторых #ifdefs. Я думаю, что это очень редкие случаи, и модульные тесты, являющиеся частью сборки, должны отловить эти изменения.
5 голосов
/ 10 марта 2009

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

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

Извините (пере) опубликовать здесь, люди часто не расширяют комментарии.

Проверьте мой комментарий к crashmstr, FlexeLint / PC-Lint сделает это за вас. Информационное сообщение 766. Это обсуждается в разделе 11.8.1 моего руководства (версия 8.0).

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

4 голосов
/ 01 июня 2011

Если вы используете Eclipse CDT, вы можете попробовать http://includator.com, который является бесплатным для бета-тестеров (на момент написания этой статьи) и автоматически удаляет лишние #include или добавляет отсутствующие. Для тех пользователей, которые имеют FlexeLint или PC-Lint и используют Elicpse CDT, http://linticator.com может быть вариантом (также бесплатно для бета-тестирования). Хотя он использует анализ Lint, он предоставляет быстрые исправления для автоматического удаления лишних операторов #include.

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