I'm creating a new framework which uses a mix of C and C++, and recently I stopped to consider my choice of header file extension.
I have spent my career as a C programmer, so many of my habits are simply ossified from my C days. One such habit is using
.h for all header file extensions.
To make matters worse, it seems there is still not a fixed approach to C/C++ header file differentiation. While surveying comments around the internet, I see many developers only use
.hpp for C++ headers which also include implementations. Other C++-only headers are left with the
.h extension. Unhelpfully, many IDEs still seem to recommend
.h as the default header extension, even if you are using C++.
The problem with allowing
.h to represent both C and C++ code without differentiation is that you increase friction for developers:
- How can you know that you can't include a specific library
.hfile in your C program because it's really C++?
- What if you are trying to adjust your build system and want to exclude all C++ files from a specific project?
I think it is important to make conventions and language type apparent to developers without requiring manual inspection. In my new framework, I have decided to use
.hpp for all headers that are C++-only.
.h will be reserved for headers which can be included by either C or C++ sources. I'm not alone in this convention - at the very least, Boost uses the same approach. To quote from the Boost FAQ:
Why do Boost headers have a .hpp suffix rather than .h or none at all?
File extensions communicate the "type" of the file, both to humans and to computer programs. The '.h' extension is used for C header files, and therefore communicates the wrong thing about C++ header files. Using no extension communicates nothing and forces inspection of file contents to determine type. Using '.hpp' unambiguously identifies it as C++ header file, and works well in actual practice. (Rainer Deyke)
As an aside, it is helpful to make your C-style headers compatible with C++. Here are some simple strategies to keep in mind:
- protect C-only code with the
__cplusplusmacro, which is only defined by the C++ compiler
- Mark C functions code as
extern "C"when compiling C++ code
I hope that you take some time to think about header extensions in your own projects!