10

I have a big project with hundreds of files. And as it often happens to C++ projects, #include directives are messed up. I want to refactor them to increase clarity, decrease compilation time and simplify analysis.

For each .h file, I want to make sure that:

  • It have #include directives only for types it is using
  • But it have only forward declarations of types that are used as T* or T&

For each .cpp file I want to make sure that:

  • It have #include directives only for types it is using and not already included by another headers (no indirect includes when possible)

I'm looking for a tool which will help me to automate this refactoring. For now, I only know of tools that help to remove redundant includes. Some of them are:

  • PC-lint
  • include-what-you-use
  • cppclean
  • ProFactor IncludeManager

But I know of no tools to help me to move necessary includes in .h files or replace includes with forward declarations. Any ideas? Tools for Windows and Visual Studio are preferred.

8

It seems like include-what-you-use (IWYU) actually does what I want. Though it is a bit difficult to use it in Windows. But there are even pre-built windows binaries available, and maintainers promise to update them with each new version of clang.

The important concept behind IWYU and its suggestions about how to change your includes is "re-exporting", as stated in docs. Basically, IWYU suggest to directly include file with declaration for each directly used entity in the code. Or forward-declare it, when possible. Unless the entity is already re-exported from other included files, i.e. in this case its declaration might be included indirectly.

It took some effort to make IWYU work with files from Visual Studio 2010 solution, but I came out with this options for include-what-you-use.exe:

include-what-you-use.exe ^
-I "%ProgramFiles(x86)%/Microsoft SDKs/Windows/v7.0A/Include" ^
-I "%ProgramFiles(x86)%/Microsoft Visual Studio 10.0/VC/include" ^
-I "<paths_to_all_your_other_included_dirs>" ^
-DWIN32 -DNDEBUG -D_WINDOWS -D_USRDLL ^
-w -x c++ -std=c++11 -fcxx-exceptions -fexceptions -fms-compatibility -fms-extensions -fmsc-version=1600 -Wno-invalid-token-paste ^
-include stdafx.h ^
-Xiwyu --verbose=2 -Xiwyu --transitive_includes_only ^
you_file.h

The -include stdafx.h options is needed when analyzing headers to provide implicitly included headers, like std or Qt. For now on, I've tested it only on .h files, not .cpp files, but it seem to work pretty well once you understand what it is actually doing. Wiki pages are really helpful.

Hope this will help someone.

| improve this answer | |
  • Brilliant your command worked straight away – Franck Mesirard Dec 17 '15 at 10:07
  • Sometimes I wish I could upvote an answer more than once. – Andreas Jun 2 '16 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.