By shoosh


2009-03-05 13:43:53 8 Comments

I often find that the headers section of a file get larger and larger all the time but it never gets smaller. Throughout the life of a source file classes may have moved and been refactored and it's very possible that there are quite a few #includes that don't need to be there and anymore. Leaving them there only prolong the compile time and adds unnecessary compilation dependencies. Trying to figure out which are still needed can be quite tedious.

Is there some kind of tool that can detect superfluous #include directives and suggest which ones I can safely remove?
Does lint do this maybe?

19 comments

@anon 2009-03-05 14:13:57

It's not automatic, but doxygen will produce dependency diagrams for #included files. You will have to go through them visually, but they can be very useful for getting a picture of what is using what.

@Tom 2009-03-06 01:36:15

This is a great way to see chains.. seeing A -> B -> C -> D and A -> D immediately reveals the redundancy.

@MikeMB 2016-02-25 22:39:06

@Tom: That is a horrible Idea: For one It doesn't show if those includes are needed or not and second, the list of includes should not depend on indirect includes that may change in the future (Redundant includes are usually not such a big problem anyway, thanks to include guards and compiler magic), but on which classes / functions are actually used in the file (Your compiler shouldn't have to go through thousands of lines of template code that don't even get instantiated)

@ap-osd 2017-04-14 10:24:58

Here is a simple brute force way of identifying superfluous header includes. It's not perfect but eliminates the "obvious" unnecessary includes. Getting rid of these goes a long way in cleaning up the code.

The scripts can be accessed directly on GitHub.

@congusbongus 2017-04-06 23:53:42

CLion, the C/C++ IDE from JetBrains, detects redundant includes out-of-the-box. These are grayed-out in the editor, but there are also functions to optimise includes in the current file or whole project.

I've found that you pay for this functionality though; CLion takes a while to scan and analyse your project when first loaded.

@Tzafrir 2011-02-22 13:48:37

Also check out include-what-you-use, which solves a similar problem.

@Dan Olson 2011-04-12 19:28:24

IMHO this answer needs a lot more upvotes, as once the kinks are worked out Google's IWYU tool will be the definitive tool for this task.

@Andrew Wagner 2015-10-15 15:21:41

sudo apt-get install iwyu

@Mawg 2016-09-07 06:47:46

Seems great - with two cavaets 1) last update Feb 2106 2) Gogole themselves use it only for C++, not C, which the OP requested.

@King's jester 2017-08-10 08:45:32

Can you explain a little bit how a user should use it ? The README isn't very clear about what contains the output of the python script.

@InQusitive 2018-02-27 14:25:09

I am using this, but it is not always 100% correct. Maybe 70% times it gives the correct suggestions.

@Josh Kelley 2009-03-05 14:43:44

Google's cppclean (links to: download, documentation) can find several categories of C++ problems, and it can now find superfluous #includes.

There's also a Clang-based tool, include-what-you-use, that can do this. include-what-you-use can even suggest forward declarations (so you don't have to #include so much) and optionally clean up your #includes for you.

Current versions of Eclipse CDT also have this functionality built in: going under the Source menu and clicking Organize Includes will alphabetize your #include's, add any headers that Eclipse thinks you're using without directly including them, and comments out any headers that it doesn't think you need. This feature isn't 100% reliable, however.

@Chance 2011-08-18 17:39:24

It does now. I just starting using it. See my note here. stackoverflow.com/questions/1301850/…

@Josh Kelley 2011-08-18 17:50:33

@Chance: Updated. Thanks.

@Chance 2011-08-23 19:00:06

I just started using Clang too. I think I like it even better.

@Nick 2013-06-14 22:45:17

The cppclean repository is down, you can now get it here: bitbucket.org/robertmassaioli/cppclean (the original site is still useful for some example usage though)

@BenC 2014-08-29 12:20:21

I updated the link to a maintained cppclean fork: github.com/myint/cppclean

@hochl 2015-04-15 06:50:19

include-what-you-use seems still in development, after a somewhat long hiatus there are news posted to the page (latest entry: 2014/11).

@Erik Sjölund 2015-06-20 07:51:06

The project include-what-you-use is still active. 4 June 2015 include-what-you-use 0.4 was released.

@Zitrax 2016-08-09 09:52:01

Note that cppclean seem to find them only in header files, not cpp files, from the doc: "Unnecessary #includes in header files".

@wizurd 2018-07-12 14:48:21

Does Eclipse CDT use google's iwyu tool under the hood?

@Josh Kelley 2018-07-12 15:19:38

@wizurd - I haven't kept up with recent developments in Eclipse CDT, but I don't think so. iwyu is thorough and relatively slow. Eclipse CDT's analysis is fast (interactive) and, when I tested it, less accurate.

@Hi-Angel 2019-09-06 12:51:30

Latest cppclean (0.13) reports lots of unused includes for Konsole sources, yet removing any results in compilation errors. include-what-you-use is a bit better in that regard: it also has lots of false-positives, but at least some of removed includes indeed weren't needed. Btw, worth noting that include-what-you-use is packaged for many GNU/Linux distros, so you don't need to install it from sources (which isn't straightforward btw). The package can go under alternative name iwyu.

@Algoman 2014-04-07 16:00:28

To end this discussion: the c++ preprocessor is turing complete. It is a semantic property, whether an include is superfluous. Hence, it follows from Rice's theorem that it is undecidable whether an include is superfluous or not. There CAN'T be a program, that (always correctly) detects whether an include is superfluous.

@shoosh 2014-04-07 20:03:33

Did I ask for an "always correct" solution? This answer is not very productive for the discussion.

@Algoman 2014-04-08 08:29:18

Well there have been numerous posts discussing problems that such a program would have to deal with. My post gives a conclusive and correct answer to that part of the discussion. And I for one would not like it, if a program told me, I could safely remove an #include and then my code doesn't compile anymore. (or worse - still compiles but does something differently). ANY such program bears this risk.

@Algoman 2014-04-09 08:50:15

Between all the SPECULATION about how hard that would be and how you MIGHT solve one obstacle or another, I gave you the only 100% correct answer. I find it quite impudent to say that this wasn't productive...

@BlamKiwi 2015-02-10 04:54:23

@Algoman taking a page from compiler design, conservative heuristics mean never having to say sorry.

@Zhe Yang 2016-01-13 14:20:45

I remembered that Rice's theorem states "There can't be a program which always can check if a given program solve this superfluous-includes problem". There can be a few programs which solve the superfluous-includes problem.

@Algoman 2016-01-15 00:11:36

If a program doesn't ALWAYS give you the correct answer, then it doesn't "SOLVE" the problem. They can only solve some non-semantic subsets of the problem.

@bogardon 2017-02-01 06:09:33

personally I found @Algoman's input very helpful. makes me realize how hard this problem is.

@Florian Castellane 2017-05-12 11:56:25

this is false. The c++ preprocessor is not Turing complete. stackoverflow.com/a/7508513/2918853

@Algoman 2017-05-14 13:44:40

Do you understand the reasoning behind that claim? Recursion-depth having an (arbitrarily chosen) limit contradicts turing completeness as much as finite RAM contradicts your PCs turing completeness.

@Benno Straub 2017-07-20 10:46:58

The recursion depth is signigicant however: No real compiler can have actual infinite recursion depth, therefore it is not turing complete making the problem solvable for any existing computer with any existing compiler.

@Algoman 2017-07-21 12:39:18

By that reasoning, the Halting Problem is solvable, because no real PC has actual infinite RAM. There is no technical necessity for a limit on the recursion depth. That is just a design-decision.

@Dan M. 2018-05-09 14:16:53

@Algoman but that means that it's solvable in practice, since the maximum recursion depth needed to compile said program is known. I.e. if the program already compiles, when it doesn't have infinite recursion, and then the include analysis can be run safely (since the complexity of getting the correct includes is not asymptotically higher than compiling the program).

@Algoman 2018-05-10 20:05:57

@DanM. that's complete nonsense. One include may set some preprocessor macro (say only it's include guard) then the next include may do something completely different based on the presence of that macro. Say it now doesn't include stdio, but defines a function named printf, which wipes your harddrive. Still compiles. Totally safe to remove that first include.

@Algoman 2018-05-10 20:12:02

Even if the preprocessor wasn't turing complete, you'd still have to GUARANTEE that the removal of the include absolutely doesn't change the semantic of ANY program that includes your file. Now we're talking about Turing-Degree 2 - that's even infinitely harder than the halting problem.

@Dan M. 2018-05-11 11:48:10

@Algoman and compiler somehow figures out what printf function to include during the compilation process, so it means that so can a hypothetical include analyzer. Also, there is no need to provide strong "GUARANTEE" that removal of some include won't affect anything down the line (if you have a lib). In fact, there can't be such guarantee because transitive includes is a thing and people often mistakenly rely on them. But in that case it's their bug, not yours. You just document which headers you include exactly and relying on everything else is UB (not part of the public interface).

@Algoman 2018-05-12 13:09:52

Oh yes, there is a need to provide a strong guarantee. Just because you (falsely) believe this didn't affect YOUR use-case only shows how little your understanding of the problem is. You are talking with an expert on this topic here and you are suffering from the Dunning-Kruger effect.

@zhaorufei 2010-12-14 06:13:01

There's two types of superfluous #include files:

  1. A header file actually not needed by the module(.c, .cpp) at all
  2. A header file is need by the module but being included more than once, directly, or indirectly.

There's 2 ways in my experience that works well to detecting it:

  • gcc -H or cl.exe /showincludes (resolve problem 2)

    In real world, you can export CFLAGS=-H before make, if all the Makefile's not override CFLAGS options. Or as I used, you can create a cc/g++ wrapper to add -H options forcibly to each invoke of $(CC) and $(CXX). and prepend the wrapper's directory to $PATH variable, then your make will all uses you wrapper command instead. Of course your wrapper should invoke the real gcc compiler. This tricks need to change if your Makefile uses gcc directly. instead of $(CC) or $(CXX) or by implied rules.

    You can also compile a single file by tweaking with the command line. But if you want to clean headers for the whole project. You can capture all the output by:

    make clean

    make 2>&1 | tee result.txt

  • PC-Lint/FlexeLint(resolve problem both 1 and 2)

    make sure add the +e766 options, this warning is about: unused header files.

    pclint/flint -vf ...

    This will cause pclint output included header files, nested header files will be indented appropriately.

@PeterSom 2011-06-01 12:52:20

If you are using Eclipse CDT you can try http://includator.com which is free for beta testers (at the time of this writing) and automatically removes superfluous #includes or adds missing ones. For those users who have FlexeLint or PC-Lint and are using Elicpse CDT, http://linticator.com might be an option (also free for beta test). While it uses Lint's analysis, it provides quick-fixes for automatically remove the superfluous #include statements.

@PeterSom 2013-12-11 08:02:37

The reason for that is that our bookkeeping department is not able to invoice lesser amounts. If you count the time you might save it is not that unreasonable. Once, we've got the ability to get credit card payments we can lower the price significantly. Another option would be a sponsor for our development efforts. Our financing model requires us to gain profits to finance our research work. I would be happy to sell licenses much cheaper, but can't. May be we will contribute it to CDT and you get it for free, but that I have to finance somehow. I forgot, you can try for free!

@Vladimir 2011-01-06 20:34:30

There is a free tool Include File Dependencies Watcher which can be integrated in the visual studio. It shows superfluous #includes in red.

@Hi-Angel 2019-09-06 12:03:26

Also doesn't work on GNU/Linux.

@rubenvb 2010-06-30 14:47:41

Maybe a little late, but I once found a WebKit perl script that did just what you wanted. It'll need some adapting I believe (I'm not well versed in perl), but it should do the trick:

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

(this is an old branch because trunk doesn't have the file anymore)

@Dan Olson 2009-03-10 10:22:46

I've never found a full-fledged tool that accomplishes what you're asking. The closest thing I've used is IncludeManager, which graphs your header inclusion tree so you can visually spot things like headers included in only one file and circular header inclusions.

@Steve Gury 2009-03-10 10:14:15

This article explains a technique of #include removing by using the parsing of Doxygen. That's just a perl script, so it's quite easy to use.

@Baptiste Wicht 2012-10-30 02:53:39

The script finds some includes to remove but it gives also a lots of includes that cannot be removed. It seems that it doesn't support class enum, seems also that it has a bad time with macro and sometimes with namespace.

@Ben Martin 2009-03-05 22:07:26

I've tried using Flexelint (the unix version of PC-Lint) and had somewhat mixed results. This is likely because I'm working on a very large and knotty code base. I recommend carefully examining each file that is reported as unused.

The main worry is false positives. Multiple includes of the same header are reported as an unneeded header. This is bad since Flexelint does not tell you what line the header is included on or where it was included before.

One of the ways automated tools can get this wrong:

In A.hpp:

class A { 
  // ...
};

In B.hpp:

#include "A.hpp

class B {
    public:
        A foo;
};

In 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

If you blindly follow the messages from Flexelint you'll muck up your #include dependencies. There are more pathological cases, but basically you're going to need to inspect the headers yourself for best results.

I highly recommend this article on Physical Structure and C++ from the blog Games from within. They recommend a comprehensive approach to cleaning up the #include mess:

Guidelines

Here’s a distilled set of guidelines from Lakos’ book that minimize the number of physical dependencies between files. I’ve been using them for years and I’ve always been really happy with the results.

  1. Every cpp file includes its own header file first. [snip]
  2. A header file must include all the header files necessary to parse it. [snip]
  3. A header file should have the bare minimum number of header files necessary to parse it. [snip]

@Tom 2009-03-06 01:38:42

Lakos's book is great for education -- aside from his outdated observations on compiler technology.

@crashmstr 2009-03-05 14:00:16

Gimpel Software's PC Lint can report on when an include file has been included more than once in a compilation unit, but it can't find include files which are not needed in the way you are looking for.

Edit: It can. See itsmatt's answer

@Dan 2009-03-05 18:57:48

Are you sure about that? I haven't used FlexeLint (same as PCL) in a few years on C++ code, but even recently on C code, I could swear I saw a couple messages (I think it's code 766?) about unused header files. Just checked (v8.0), see section 11.8.1. of manual.

@Dan 2009-03-05 19:02:11

Sorry to (re-)post here, people often don't expand comments.

Check my comment to crashmstr, FlexeLint / PC-Lint will do this for you. Informational message 766. Section 11.8.1 of my manual (version 8.0) discusses this.

Also, and this is important, keep iterating until the message goes away. In other words, after removing unused headers, re-run lint, more header files might have become "unneeded" once you remove some unneeded headers. (That might sound silly, read it slowly & parse it, it makes sense.)

@David Thornley 2009-03-05 19:12:14

I know exactly what you mean, and my reaction was "Ewwww". I hate code like that.

@JaredPar 2009-03-05 13:51:53

The problem with detecting superfluous includes is that it can't be just a type dependency checker. A superfluous include is a file which provides nothing of value to the compilation and does not alter another item which other files depend. There are many ways a header file can alter a compile, say by defining a constant, redefining and/or deleting a used macro, adding a namespace which alters the lookup of a name some way down the line. In order to detect items like the namespace you need much more than a preprocessor, you in fact almost need a full compiler.

Lint is more of a style checker and certainly won't have this full capability.

I think you'll find the only way to detect a superfluous include is to remove, compile and run suites.

@David Thornley 2009-03-05 14:50:01

None of this will be an issue if the include files are laid out well. If you ever need to include file A before file B, you're doing it wrong (and I've worked on projects where they did it wrong).

@JaredPar 2009-03-05 15:38:24

@David, yes but that depends on the years of devs before you doing it correctly. I can say with great certainty that the odds of that happening favor the house, not you :(

@David Thornley 2009-03-05 19:10:32

Yes, but I generally find out about that when modifying a program, and suddenly I've got a compilation error (if I'm lucky) or an obscure bug. That seems to keep the #include files honest, at least in the long run.

@Benoît 2009-03-05 20:30:37

I'd say the exact contrary. All you need is a type dependency checker. It might not compile after you've arranged includes accordingly, but these are problems that should be dealt with anyway.

@JaredPar 2009-03-05 20:45:15

@Benoit, then you would be ignoring a class of issues that compile but semantically change the meaning of your program. Consider how a #define in one file can alter a #if branch in another. Removing a header can still allow this to compile with different results

@Dan 2009-03-06 04:26:04

I could be wrong here (again - I should try it & post facts, not post on my best recollection...) but I'm pretty sure that PC-Lint / Flexelint will detect if a header influences/alters the compilation in any way. Regular lint, not so sure...

@Diomidis Spinellis 2009-03-05 14:53:07

The CScout refactoring browser can detect superfluous include directives in C (unfortunately not C++) code. You can find a description of how it works in this journal article.

@Gilad Naor 2009-03-05 14:10:49

You can write a quick script that erases a single #include directive, compiles the projects, and logs the name in the #include and the file it was removed from in the case that no compilation errors occurred.

Let it run during the night, and the next day you will have a 100% correct list of include files you can remove.

Sometimes brute-force just works :-)


edit: and sometimes it doesn't :-). Here's a bit of information from the comments:

  1. Sometimes you can remove two header files separately, but not both together. A solution is to remove the header files during the run and not bring them back. This will find a list of files you can safely remove, although there might a solution with more files to remove which this algorithm won't find. (it's a greedy search over the space of include files to remove. It will only find a local maximum)
  2. There may be subtle changes in behavior if you have some macros redefined differently depending on some #ifdefs. I think these are very rare cases, and the Unit Tests which are part of the build should catch these changes.

@Dominic Rodger 2009-03-05 14:21:19

Be careful of this - say there are two header files which both include a definition of something. You can remove either, but not both. You'll need to be a bit more thorough in your brute force approach.

@Dominic Rodger 2009-03-05 14:21:58

Maybe this is what you meant, but a script that removes a single include, and leaves the last removed include out if it was successfully removed would do the trick.

@Graeme Perrow 2009-03-05 14:31:38

Bad idea. If a header file #defines a constant BLAH and another header file checks #ifdef BLAH, removing the first header file may still successfully compile but your behaviour has changed.

@Gilad Naor 2009-03-05 14:31:51

Didn't think about it too much, but you are correct. God is in the details, as they say. I'm not sure leaving the .h file out at each step is sufficient - this is still a Greedy search (capitol G), which doesn't always find the optimal solution. It will give a CORRECT solution, unlike the original.

@Gilad Naor 2009-03-05 14:33:11

@Graeme - Hopefully the Unit-Tests, which are part of the build (hopefully) will catch such faults.

@David Thornley 2009-03-05 14:52:45

This also can cause problems with system headers, since different implementations might have different things included in #include <vector>. Even if you stick to one compiler, the headers could change over different versions.

@bk1e 2009-03-05 15:44:43

This won't find cases where you're including a header that includes the header that you really need.

@itsmatt 2009-03-05 13:47:47

I thought that PCLint would do this, but it has been a few years since I've looked at it. You might check it out.

I looked at this blog and the author talked a bit about configuring PCLint to find unused includes. Might be worth a look.

@crashmstr 2009-03-05 14:17:10

Good find! I'll have to use that.

@Harold Bamford 2009-03-05 17:23:25

I use PCLint regularly and it does tell me of unused headers. I'm careful to comment out the header #include and re-compile to be sure that the header is truly unused...

@itsmatt 2009-03-05 17:26:58

Thanks for the confirmation, Harold.

@Matthieu N. 2011-01-02 07:08:01

too expensive. not a viable tool for the masses.

Related Questions

Sponsored Content

23 Answered Questions

[SOLVED] What is the "-->" operator in C++?

17 Answered Questions

[SOLVED] How can I profile C++ code running on Linux?

  • 2008-12-17 20:29:24
  • Gabriel Isenberg
  • 494490 View
  • 1742 Score
  • 17 Answer
  • Tags:   c++ unix profiling

58 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

37 Answered Questions

24 Answered Questions

[SOLVED] Difference between require, include, require_once and include_once?

13 Answered Questions

[SOLVED] What is the effect of extern "C" in C++?

10 Answered Questions

[SOLVED] Improve INSERT-per-second performance of SQLite?

1 Answered Questions

[SOLVED] The Definitive C++ Book Guide and List

  • 2008-12-23 05:23:56
  • grepsedawk
  • 2251388 View
  • 4246 Score
  • 1 Answer
  • Tags:   c++ c++-faq

27 Answered Questions

10 Answered Questions

Sponsored Content