*.h or *.hpp for your class definitions
I use .hpp because I want the user to differentiate what headers are C++ headers, and what headers are C headers.
This can be important when your project is using both C and C++ modules: Like someone else explained before me, you should do it very carefully, and its starts by the "contract" you offer through the extension
.hpp : C++ Headers
(Or .hxx, or .hh, or whatever)
This header is for C++ only.
If you're in a C module, don't even try to include it. You won't like it, because no effort is done to make it C-friendly (too much would be lost, like function overloading, namespaces, etc. etc.).
.h : C/C++ compatible or pure C Headers
This header can be included by both a C source, and a C++ source, directly or indirectly.
It can included directly, being protected by the __cplusplus
macro:
- Which mean that, from a C++ viewpoint, the C-compatible code will be defined as
extern "C"
. - From a C viewpoint, all the C code will be plainly visible, but the C++ code will be hidden (because it won't compile in a C compiler).
For example:
#ifndef MY_HEADER_H
#define MY_HEADER_H
#ifdef __cplusplus
extern "C"
{
#endif
void myCFunction() ;
#ifdef __cplusplus
} // extern "C"
#endif
#endif // MY_HEADER_H
Or it could be included indirectly by the corresponding .hpp header enclosing it with the extern "C"
declaration.
For example:
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
extern "C"
{
#include "my_header.h"
}
#endif // MY_HEADER_HPP
and:
#ifndef MY_HEADER_H
#define MY_HEADER_H
void myCFunction() ;
#endif // MY_HEADER_H
Here are a couple of reasons for having different naming of C vs C++ headers:
- Automatic code formatting, you might have different guidelines for formatting C and C++ code. If the headers are separated by extension you can set your editor to apply the appropriate formatting automatically
- Naming, I've been on projects where there were libraries written in C and then wrappers had been implemented in C++. Since the headers usually had similar names, i.e. Feature.h vs Feature.hpp, they were easy to tell apart.
- Inclusion, maybe your project has more appropriate versions available written in C++ but you are using the C version (see above point). If headers are named after the language they are implemented in you can easily spot all the C-headers and check for C++ versions.
Remember, C is not C++ and it can be very dangerous to mix and match unless you know what you are doing. Naming your sources appropriately helps you tell the languages apart.
I always considered the .hpp
header to be a sort of portmanteau of .h
and .cpp
files...a header which contains implementation details as well.
Typically when I've seen (and use) .hpp
as an extension, there is no corresponding .cpp
file. As others have said, this isn't a hard and fast rule, just how I tend to use .hpp
files.