25

Are there any tools that help organizing the #includes that belong at the top of a .c or .h file?

I was just wondering because I am reorganizing my code, moving various small function definitions/declarations from one long file into different smaller files. Now each of the smaller files needs a subset of the #includes that were at the top of the long file.

It's just annoying and error-prone to figure out all #includes by hand. Often the code compiles even though not all #includes are there. Example: File A uses std::vector extensively but doesn't include vector; but it currently includes some obscure other header which happens to include vector (maybe through some recursive includes).

Frank
  • 64,140
  • 93
  • 237
  • 324
  • I found a discussion of this problem on the Eclipse CDT site: http://wiki.eclipse.org/CDT/C_editor_enhancements/Include_management – Frank Sep 05 '10 at 04:06

6 Answers6

2

VisualAssistX can help you jumping to the definition of a type. E.g. if you use a class MyClass in your source, you can click it, choose goto definition, and VisualAssistX opens the include file that contains the definition of this class (possibly Visual Studio can also do this, but at this point am so getting used to VisualAssistX, that I contribute every wonderful feature to VisualAssistX :-)). You can use this to find the include file necessary for your source code.

PC-Lint can do exactly the opposite. If you have an include file in your source that is not being used, PC-Lint can warn you about it, so that you know that the include file can be removed from the source (which will have a positive impact on your compilation time).

Patrick
  • 23,217
  • 12
  • 67
  • 130
1

Since this question has been asked a new tool has been created: include-what-you-use, it is based on clang, provides mappings to fake the existence of certain symbols (unique_ptr in memory, but actually defined in bits/unique_ptr.h in some standard headers and lets you provide your own mappings.

It provides nice diagnostics and automatic rewriting.

pmr
  • 58,701
  • 10
  • 113
  • 156
1

Now each of the smaller files needs a subset of the #includes that were at the top of the long file.

I do this using VisualAssistX. Firstly compile the file to see what is missing. Then you can use VisualAssistX's Add include function. So I just go and right-click on the functions or classes that I know need an include and hit Add Include. Recompile a couple of times to filter out new missing includes and it is done. I hope I wrote that understandably :)

Not perfect, but faster than doing it by hand.

rozina
  • 4,120
  • 27
  • 49
1

makedepend and gccmakedep

msw
  • 42,753
  • 9
  • 87
  • 112
  • Good idea, but probably not exactly what I need. I'd like a tool that tells me what I should include, even if I haven't added a single include yet (makedepend and friends would give an error in that case). Eclipse does that for Java (maybe for C++ too?). Also, makedepend tells me the dependencies for each compilation unit (`.o` file), but not what a certain header file should include. – Frank Sep 04 '10 at 23:42
  • 3
    I think the problem as you pose it is uninvertable. For example, I can run a program that tells me that `EOF` is undefined in `foo.c`. I can also mechanically determine that EOF is defined in `libio.h`, `stdio.h` and (e.g.) `foo.h`. Which do I include? – msw Sep 05 '10 at 00:09
  • 4
    you present a valid point. However, a tool could still make suggestions, based on which headers are present in the include path, and perhaps even which are standard (or popular). – Matthew Flaschen Sep 05 '10 at 02:43
  • 2
    It would also be useful to know what header files that are included have no effect on the compilation. Certainly, one could drop one header at a time and compile, but there must be an easier way. That would catch the common case of a header that was required in an earlier revision, but which is now unnecessary. – RBerteig Sep 05 '10 at 08:55
  • @RBerteig: One possibility is to write a tool that deletes the include lines one-by-one and tries to compile the source program. If after removing an include there are no errors, that include can be removed. – Giorgio Jul 25 '11 at 20:28
  • @Giorgio, I'd also want the regression tests to pass. I've seen include files that change semantics if included in ways that don't break the compile but do change behavior. I don't think any of the standard includes do that, but.... – RBerteig Jul 28 '11 at 18:45
  • @RBerteig: You are right! The include files in my project should only define classes, types, and macros. But this is not true in general. I think that instead of fancy things such as lambda expressions, C++ should be extended with a proper module concept making it possible to rearrange imports. That would speed up compilation a lot. – Giorgio Jul 29 '11 at 04:53
  • I wrote a tool that Reports on useless includes. It uses brute force to remove one include statement at a time, saves it to a temporary file and attempts to compile it. Then it reports the files that succeeded. I even made it multi-threaded. Using C# the tool was barely 200 lines of code. – C.J. Oct 30 '11 at 10:23
1

I have been dealing with this problem lately. In our project we use C++ and have one X.h and one X.cpp file for each class X.

My strategy is the following:

(1) If A.h, where class A is declared, refers to a class B, then I have to include header B.h. If the declaration of class A contains only the type *B, then I only need a forward declaration class B; in A.h. I might need to include B.h in A.cpp

(2) Using the above procedure, I move as many includes as possible from A.h to A.cpp. Then I try removing one include at a time and see if the .cpp file still compiles. This should allow to minimize the set of included files in the .cpp file, but I am not 100% sure if the result is minimal. I also think one can write a tool to do this automatically. I had started to write one for Visual Studio. I would be glad to know that there are such tools.

Note: maybe adding a proper module construct with well-defined import / export relations could be a desired addition for C++0x. It would make the task of reorganizing imports much easier and speed up compilation a lot.

Giorgio
  • 5,023
  • 6
  • 41
  • 71
0

I use the doxygen/dot-graphviz generated graphs to see how files are linked. Very handy, but not automatic, you have to visually check the graphs, then edit you code to remove unnecessary "#include" lines. Of course, not really suited for very-large projects (say > 100 files), where the graphs become unusable.

kebs
  • 6,387
  • 4
  • 41
  • 70