Обнаружение лишних #includes в C / C ++?

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

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


person shoosh    schedule 05.03.2009    source источник
comment
См. Также: stackoverflow.com/questions/74326/   -  person Eclipse    schedule 19.06.2009
comment
Связанный вопрос, похоже, решает проблему только в Windows, в частности с использованием Visual Studio.   -  person D'Nabre    schedule 07.11.2014
comment
Голосование за повторное открытие, поскольку дубликат, в частности, касается использования Visual Studio.   -  person Drew Dormann    schedule 14.05.2015


Ответы (19)


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

person Community    schedule 05.03.2009
comment
Это отличный способ увидеть цепочки. Просмотр A - ›B -› C - ›D и A -› D сразу обнаруживает избыточность. - person Tom; 06.03.2009
comment
@Tom: Это ужасная идея: во-первых, она не показывает, нужны ли те включения или нет, а во-вторых, список включений не должен зависеть от косвенных включений, которые могут измениться в будущем (избыточные включения обычно не такие в любом случае большая проблема, благодаря включению охранников и магии компилятора), но о том, какие классы / функции фактически используются в файле (вашему компилятору не нужно проходить тысячи строк кода шаблона, которые даже не создаются) - person MikeMB; 26.02.2016
comment
@albert, можете ли вы включить снимки экрана и кратко описать, где щелкнуть в выводе doxygen? - person Gabriel Staples; 12.05.2020
comment
@GabrielStaples Это не мой ответ, поэтому я не хочу добавлять к нему информацию. Я только исправил ссылку (поскольку хостинг остановлен / заблокирован для использования). - person albert; 12.05.2020

Cppclean от Google (ссылки на: загрузить, documentation) может найти несколько категорий проблем C ++, а теперь может найти лишние #includes.

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

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

person Josh Kelley    schedule 05.03.2009
comment
Теперь это так. Я только начинаю им пользоваться. Смотрите мою заметку здесь. stackoverflow.com/questions/1301850/ - person Chance; 18.08.2011
comment
Я тоже только начал использовать Clang. Думаю, он мне даже больше нравится. - person Chance; 23.08.2011
comment
Репозиторий cppclean не работает, теперь вы можете получить его здесь: bitbucket.org/robertmassaioli/cppclean ( исходный сайт все еще полезен для некоторых примеров использования) - person Nick; 15.06.2013
comment
Я обновил ссылку на поддерживаемый форк cppclean: github.com/myint/cppclean - person BenC; 29.08.2014
comment
Похоже, что include-what-you-use все еще находится в разработке, после некоторого длительного перерыва на странице публикуются новости (последняя запись: 2014/11). - person hochl; 15.04.2015
comment
Проект include-what-you-use все еще активен. 4 июня 2015 г. была выпущена версия include-what-you-use 0.4. - person Erik Sjölund; 20.06.2015
comment
Обратите внимание, что cppclean, похоже, находит их только в файлах заголовков, а не файлах cpp, из документа: Ненужные #includes в файлах заголовков. - person Zitrax; 09.08.2016
comment
Использует ли Eclipse CDT инструмент Google iwyu под капотом? - person wizurd; 12.07.2018
comment
@wizurd - Я не следил за последними разработками в Eclipse CDT, но я так не думаю. iwyu является тщательным и относительно медленным. Анализ Eclipse CDT выполняется быстро (интерактивно) и, когда я его тестировал, менее точен. - person Josh Kelley; 12.07.2018
comment
Последний cppclean (0.13) сообщает о большом количестве неиспользуемых включений для исходных кодов Konsole, но при этом удаляет любые результаты ошибок компиляции. include-what-you-use в этом отношении немного лучше: у него также много ложных срабатываний, но по крайней мере некоторые из удаленных включений действительно не нужны. Кстати, стоит отметить, что include-what-you-use упакован для многих дистрибутивов GNU / Linux, поэтому вам не нужно устанавливать его из исходников (что, кстати, непросто). Пакет может идти под альтернативным именем iwyu. - person Hi-Angel; 06.09.2019
comment
Вау, встроенная в него функция Eclipse - это круто! Я никогда не знал, что такое существует. Я могу добавить его в свой Eclipse doc. - person Gabriel Staples; 12.05.2020

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

person Tzafrir    schedule 22.02.2011
comment
ИМХО, этот ответ требует гораздо больше голосов, так как, как только все недостатки будут устранены, инструмент Google IWYU станет окончательным инструментом для этой задачи. - person Dan Olson; 12.04.2011
comment
sudo apt-get install iwyu - person Andrew Wagner; 15.10.2015
comment
Отлично - с двумя каваетами 1) последнее обновление, февраль 2106 2) Gogole сами используют его только для C ++, а не для C, который запрашивал OP. - person Mawg says reinstate Monica; 07.09.2016
comment
Не могли бы вы немного объяснить, как его использовать? В README не очень ясно, что содержит вывод скрипта python. - person Ben_LCDB; 10.08.2017
comment
Я использую это, но не всегда на 100% правильно. Может быть, в 70% раз он дает правильные предложения. - person InQusitive; 27.02.2018

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

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

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

person JaredPar    schedule 05.03.2009
comment
Ничего из этого не будет проблемой, если включаемые файлы хорошо разложены. Если вам когда-нибудь понадобится включить файл A перед файлом B, вы делаете это неправильно (и я работал над проектами, где они сделали это неправильно). - person David Thornley; 05.03.2009
comment
@ Дэвид, да, но это зависит от того, сколько лет разработчики сделали, прежде чем вы сделаете это правильно. Я могу с большой уверенностью сказать, что вероятность того, что это произойдет, в пользу дома, а не вам :( - person JaredPar; 05.03.2009
comment
Да, но обычно я узнаю об этом при изменении программы, и внезапно у меня возникает ошибка компиляции (если мне повезет) или непонятная ошибка. Похоже, что это сохраняет честность файлов #include, по крайней мере, в долгосрочной перспективе. - person David Thornley; 05.03.2009
comment
Я бы сказал прямо противоположное. Все, что вам нужно, это средство проверки зависимости типов. Он может не скомпилироваться после того, как вы соответствующим образом настроите include, но это проблемы, с которыми все равно нужно бороться. - person Benoît; 05.03.2009
comment
@Benoit, тогда вы проигнорируете класс проблем, которые компилируются, но семантически изменяют значение вашей программы. Подумайте, как #define в одном файле может изменить ветку #if в другом. Удаление заголовка все еще может позволить компиляции с другими результатами - person JaredPar; 05.03.2009
comment
Я могу ошибаться здесь (опять же - я должен попробовать и публиковать факты, а не публиковать свои лучшие воспоминания ...), но я почти уверен, что PC-Lint / Flexelint обнаружит, влияет ли заголовок / изменяет компиляцию в любом способ. Обычный ворс, не уверен ... - person Dan; 06.03.2009

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

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

person itsmatt    schedule 05.03.2009
comment
Хорошая находка! Я должен использовать это. - person crashmstr; 05.03.2009
comment
Я регулярно использую PCLint, и он сообщает мне о неиспользуемых заголовках. Я стараюсь закомментировать заголовок #include и перекомпилировать, чтобы убедиться, что заголовок действительно не используется ... - person Harold Bamford; 05.03.2009
comment
Спасибо за подтверждение, Гарольд. - person itsmatt; 05.03.2009
comment
слишком дорогой. не жизнеспособный инструмент для масс. - person ; 02.01.2011

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

person Diomidis Spinellis    schedule 05.03.2009

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

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

Иногда просто срабатывает брутфорс :-)


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

  1. Иногда можно удалить два файла заголовков по отдельности, но не оба вместе. Решение состоит в том, чтобы удалить файлы заголовков во время выполнения и не возвращать их. Будет найден список файлов, которые вы можете безопасно удалить, хотя может быть решение с большим количеством файлов для удаления, которые этот алгоритм не найдет. (это жадный поиск по пространству включаемых файлов для удаления. Будет найден только локальный максимум)
  2. В поведении могут быть небольшие изменения, если некоторые макросы переопределены по-разному в зависимости от некоторых #ifdef. Я думаю, что это очень редкие случаи, и модульные тесты, которые являются частью сборки, должны улавливать эти изменения.
person Gilad Naor    schedule 05.03.2009
comment
Будьте осторожны - скажем, есть два файла заголовков, которые содержат определение чего-либо. Вы можете удалить одно из них, но не оба сразу. Вам нужно будет более тщательно подходить к использованию грубой силы. - person Dominic Rodger; 05.03.2009
comment
Может быть, это то, что вы имели в виду, но сценарий, который удаляет одно включение и оставляет последнее удаленное включение, если оно было успешно удалено, сработает. - person Dominic Rodger; 05.03.2009
comment
Плохая идея. Если файл заголовка # определяет константу BLAH, а другой файл заголовка проверяет #ifdef BLAH, удаление первого файла заголовка может по-прежнему успешно скомпилироваться, но ваше поведение изменилось. - person Graeme Perrow; 05.03.2009
comment
Не особо об этом задумывался, но вы правы. Как говорится, Бог кроется в деталях. Я не уверен, что достаточно оставлять файл .h на каждом этапе - это все еще жадный поиск (capitol G), который не всегда находит оптимальное решение. Это даст ПРАВИЛЬНОЕ решение, в отличие от оригинала. - person Gilad Naor; 05.03.2009
comment
@Graeme - Надеюсь, модульные тесты, которые являются частью сборки (надеюсь), выявляют такие ошибки. - person Gilad Naor; 05.03.2009
comment
Это также может вызвать проблемы с системными заголовками, поскольку в разных реализациях могут быть разные вещи, включенные в #include ‹vector›. Даже если вы будете использовать один компилятор, заголовки могут меняться в разных версиях. - person David Thornley; 05.03.2009
comment
Это не найдет случаев, когда вы включаете заголовок, который включает заголовок, который вам действительно нужен. - person bk1e; 05.03.2009

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

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

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

person Dan    schedule 05.03.2009
comment
Я точно знаю, что вы имеете в виду, и моя реакция была Фууу. Я ненавижу такой код. - person David Thornley; 05.03.2009

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

person Dan Olson    schedule 10.03.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 зависимости. Есть и другие патологические случаи, но в основном вам нужно будет проверить заголовки самостоятельно для достижения наилучших результатов.

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

Руководящие указания

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

  1. Каждый файл cpp сначала включает собственный файл заголовка. [отрывок]
  2. Заголовочный файл должен включать все заголовочные файлы, необходимые для его анализа. [отрывок]
  3. Заголовочный файл должен иметь минимальное количество заголовочных файлов, необходимое для его анализа. [отрывок]
person Ben Martin    schedule 05.03.2009
comment
Книга Лакоса отлично подходит для образования - если не считать его устаревшие наблюдения о технологии компиляции. - person Tom; 06.03.2009

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

person PeterSom    schedule 01.06.2011
comment
Причина в том, что наша бухгалтерия не может выставлять счета на меньшие суммы. Если посчитать время, которое можно сэкономить, это не так уж и неразумно. Как только у нас появится возможность получать платежи по кредитным картам, мы сможем значительно снизить цену. Другой вариант - спонсорство наших усилий по развитию. Наша модель финансирования требует от нас получения прибыли для финансирования наших исследовательских работ. Я был бы рад продавать лицензии намного дешевле, но не могу. Может быть, мы внесем его в CDT, и вы получите его бесплатно, но это я должен как-то профинансировать. Забыл, можно бесплатно попробовать! - person PeterSom; 11.12.2013

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

person Steve Gury    schedule 10.03.2009
comment
Сценарий находит некоторые включения, которые нужно удалить, но также дает множество включений, которые нельзя удалить. Кажется, что он не поддерживает перечисление классов, также кажется, что ему плохо с макросом, а иногда и с пространством имен. - person Baptiste Wicht; 30.10.2012

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

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

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

person rubenvb    schedule 30.06.2010

Существует бесплатный инструмент Include File Dependencies Watcher, который можно интегрировать в визуальную студию. Он показывает лишние #includes красным.

person Vladimir    schedule 06.01.2011

Есть два типа лишних файлов #include:

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

По моему опыту, есть два способа его обнаружения:

  • gcc -H или cl.exe / showincludes (решение проблемы 2)

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

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

    очистить

    сделать 2> & 1 | тройник result.txt

  • PC-Lint / FlexeLint (решение проблемы как 1, так и 2)

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

    pclint / flint -vf ...

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

person zhaorufei    schedule 14.12.2010

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

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

person congusbongus    schedule 06.04.2017

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

Доступ к скриптам можно получить непосредственно на GitHub.

person ap-osd    schedule 14.04.2017

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

Изменить: Может. См. ответ itsmatt

person crashmstr    schedule 05.03.2009
comment
Вы уверены в этом? Я не использовал FlexeLint (так же, как PCL) в течение нескольких лет в коде C ++, но даже недавно, работая с кодом C, могу поклясться, что видел пару сообщений (я думаю, это код 766?) О неиспользуемых файлах заголовков. Только что проверил (v8.0), см. Раздел 11.8.1. руководства. - person Dan; 05.03.2009

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

person Algoman    schedule 07.04.2014
comment
Я просил всегда правильное решение? Этот ответ не очень продуктивен для обсуждения. - person shoosh; 08.04.2014
comment
Что ж, было множество сообщений, в которых обсуждались проблемы, с которыми придется иметь дело такой программе. Мой пост дает исчерпывающий и правильный ответ на эту часть обсуждения. И мне, например, не понравилось бы, если бы программа сказала мне, что я мог бы безопасно удалить #include, и тогда мой код больше не компилируется. (или того хуже - все еще компилируется, но делает что-то по-другому). Такой риск несет ЛЮБАЯ такая программа. - person Algoman; 08.04.2014
comment
Между всеми СПЕКУЛЯЦИЯМИ о том, насколько это будет сложно и как вы МОЖЕТЕ преодолеть то или иное препятствие, я дал вам единственный на 100% правильный ответ. Сказать, что это было непродуктивно, я считаю наглым ... - person Algoman; 09.04.2014
comment
@Algoman берет страницу из проекта компилятора, консервативная эвристика означает, что никогда не нужно извиняться. - person BlamKiwi; 10.02.2015
comment
Я вспомнил, что теорема Райса гласит, что не может быть программы, которая всегда может проверить, решает ли данная программа эту проблему с лишними включениями. Может быть несколько программ, которые решают проблему с лишним включением. - person Zhe Yang; 13.01.2016
comment
Если программа не ВСЕГДА дает правильный ответ, она не решает проблему. Они могут решить только некоторые несемантические подмножества проблемы. - person Algoman; 15.01.2016
comment
лично я нашел очень полезным вклад @Algoman. заставляет меня понять, насколько сложна эта проблема. - person bogardon; 01.02.2017
comment
это неправда. Препроцессор C ++ не завершен по Тьюрингу. stackoverflow.com/a/7508513/2918853 - person Florian Castellane; 12.05.2017
comment
Вы понимаете причины этого утверждения? Глубина рекурсии, имеющая (произвольно выбранный) предел, противоречит полноте по Тьюрингу, так же как ограниченная ОЗУ противоречит полноте Тьюринга вашего ПК. - person Algoman; 14.05.2017
comment
Однако глубина рекурсии значительна: ни один настоящий компилятор не может иметь фактическую бесконечную глубину рекурсии, поэтому он не является полным по Тьюрингу, что делает проблему решаемой для любого существующего компьютера с любым существующим компилятором. - person Benno Straub; 20.07.2017
comment
Исходя из этого, проблема остановки разрешима, потому что ни один настоящий компьютер не имеет бесконечной оперативной памяти. Нет технической необходимости в ограничении глубины рекурсии. Это просто дизайнерское решение. - person Algoman; 21.07.2017
comment
@Algoman, но это означает, что она разрешима на практике, поскольку известна максимальная глубина рекурсии, необходимая для компиляции указанной программы. Т.е. если программа уже компилируется, когда у нее нет бесконечной рекурсии, и тогда можно безопасно запустить анализ включения (поскольку сложность получения правильных включений не асимптотически выше, чем при компиляции программы). - person Dan M.; 09.05.2018
comment
@DanM. это полная чушь. Одно включение может установить некоторый макрос препроцессора (скажем, только его защиту включения), тогда следующее включение может делать что-то совершенно другое в зависимости от наличия этого макроса. Скажем, теперь он не включает stdio, но определяет функцию с именем printf, которая очищает ваш жесткий диск. По-прежнему компилируется. Абсолютно безопасно удалить это первое включение. - person Algoman; 10.05.2018
comment
Даже если препроцессор не был завершен по Тьюрингу, вам все равно придется ГАРАНТИРОВАТЬ, что удаление включения абсолютно не меняет семантику ЛЮБОЙ программы, которая включает ваш файл. Теперь мы говорим о степени Тьюринга 2 - это даже бесконечно сложнее, чем проблема остановки. - person Algoman; 10.05.2018
comment
@Algoman и компилятор каким-то образом выясняют, какую printf функцию включить в процесс компиляции, так что это означает, что гипотетический анализатор включения тоже может. Кроме того, нет необходимости предоставлять строгую ГАРАНТИЮ, что удаление некоторых включений не повлияет ни на что в дальнейшем (если у вас есть библиотека). На самом деле такой гарантии не может быть, потому что транзитивные включения - это вещь, и люди часто ошибочно полагаются на них. Но в таком случае это их ошибка, а не ваша. Вы просто документируете, какие заголовки вы включаете в точности, и полагаетесь на все остальное - UB (не часть общедоступного интерфейса). - person Dan M.; 11.05.2018
comment
Ах да, необходимо дать сильную гарантию. Тот факт, что вы (ошибочно) полагаете, что это не повлияло на ВАШ вариант использования, только показывает, насколько мало вы понимаете проблему. Вы здесь разговариваете со специалистом по этой теме и страдаете от эффекта Даннинга-Крюгера. - person Algoman; 12.05.2018