Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Header inclusion optimization

Tags:

Is there an automatic way to optimize inclusion of header files in C++, so that compilation time is improved ? With the word "automatic" I mean a tool or program. Is it possible to find which headers files are obsolete (e.g exposed functionality is not used) ?

Edit: Having each include header "included only once is one important thing, but is there a way to even change the contents of files so that frequently used "functionality" is on specific includes and less frequently used functionality is on other includes? Am i asking too much ? Unfortunately, we are talking about an existing code base with thousands of files. Could it be a refactoring tool what I am actually asking for ?

Thank you.

like image 222
John Avatar asked Dec 08 '09 19:12

John


People also ask

How do you prevent multiple inclusions of header files?

To avoid multiple inclusions of the same header file we use the #ifndef, #define and #endif preprocessor directives. Just write the entire program in only file and include headers once only.

Why header file inclusion is must?

Including Multiple Header Files: You can use various header files in a program. When a header file is included twice within a program, the compiler processes the contents of that header file twice. This leads to an error in the program. To eliminate this error, conditional preprocessor directives are used.

What is multiple inclusion of header files?

If a header file happens to be included twice, the compiler will process its contents twice. This is very likely to cause an error, e.g. when the compiler sees the same structure definition twice. Even if it does not, it will certainly waste time.

Why header file inclusion is must in C?

Header files serve two purposes. System header files declare the interfaces to parts of the operating system. You include them in your program to supply the definitions and declarations you need to invoke system calls and libraries.


2 Answers

Update

I think what you really want is "include what you use" rather than a minimal set of headers. IWYU means forward declare as much as possible, and include headers that directly declare the symbols you use. You cannot mindlessly convert a file to be IWYU clean as it may no longer compile. When that occurs, you need to find the missing header and add it. However, if every file is IWYU clean your compiles will be faster overall even if you have to add headers occasionally. Not to mention you headers will be more meaningful/self-documenting.

As my previous answer points out it is technically possible to include even fewer headers than necessary for IWYU, but it's generally a waste of time.

Now if only there was a tool to most of the IWYU refactoring grunt work for you :)

  • Google's IWYU
  • Include What You Use

I had considered a creating/using a tool like this once. The idea is to use binary search and repeated compilation to find the minimal set of includes. Upon further investigation it didn't seem that useful.

Some issues:

  • Changing the included header files can change the behavior, and still allow the file to compile. One example in particular, if you defined your own std::swap in a separate header file. You could remove that header and your code would still compile using the default std::swap implementation. However, the std::swap may be: inefficient, cause a runtime error, or worse produce subtly wrong logic.

  • Sometimes a header file inclusion works as documentation. For instance, to used std::foreach, often including <vector> is sufficient to get it to compile. The code is more meaningful with the extra #include <algorithm>.

  • The minimal compilation set may not be portable, between compilers or compiler versions. Using the std::foreach example again, there is no guarantee that std::foreach will provided in by <vector>.

  • The minimal set of includes may not affect compile time significantly anyway. Visual studio and gcc support #pragma once which make repeated included essentially non-existent performance wise. And at least gcc's preprocessor has been optimized to process include guards very fast (as fast as #pragma once).

like image 191
deft_code Avatar answered Oct 13 '22 13:10

deft_code


Most compilers have some kind of support for precompiled header files.

A tool that removes totally unneeded includes might be nice. You seem to be implying that you'd like to see one that removes needed includes that are rendered redundant by other includes. That I wouldn't be a big fan of. Somebody could remove the other redundant include one day, and then some other poor slob will have to track down what include file somewhere on the hard disk has all those missing symbols that suddenly appeared on them for no apparent reason.

like image 25
T.E.D. Avatar answered Oct 13 '22 14:10

T.E.D.