.h or .hpp for C++ header files? Settling it once and for all
If you've ever written in C++ for more than a couple of weeks, you've likely encountered this question. You open someone else's project — there's .h. You start your own — a voice in your head says: "Maybe .hpp is cooler?". Or vice versa: you're a die-hard fan of .h, while a colleague insists that .hpp is the one true path.
Spoiler: both options are technically correct. The compiler doesn't care. But there is a difference, and it matters for code organization, readability, and project maintenance. Let's figure out what lies behind these two extensions and when to choose which.
Short answer: what's the fundamental difference?
In a nutshell:
.h— the traditional extension for header files, inherited from C. Used in both C and C++..hpp— a more modern extension that explicitly indicates: "This is C++, not C." It was created to distinguish C++ headers from C ones.
But the devil, as always, is in the details. Let's dig deeper.
Historical context: where did .h and .hpp come from?
The C language has used .h for headers since time immemorial. When C++ appeared, programmers initially just kept using .h — and that's fine. The C++ standard library (e.g., <iostream>) actually abandoned extensions altogether, but that's another story.
The .hpp extension emerged as a response to the need to separate C and C++ code. Imagine: you have a large project where some files are in C and some in C++. You build it, possibly with different compilers or different flags. How do you quickly tell which header is for which language? That's right — look at the extension.
Thus, .hpp (from "C Plus Plus header") became the de facto standard in the community for pure C++ headers, especially in libraries like Boost.
When to use .h?
Don't rush to bury .h. It has its strengths:
- C compatibility. If your header file needs to be included from both C and C++ code — only
.h. No alternatives. - Conservative projects. In large codebases where the style has been established for years, changing extensions to
.hppis unnecessary hassle. - Minimalism. Three characters instead of four. A small thing, but nice.
Example: a header compatible with C and C++
// math_utils.h#ifndef MATH_UTILS_H#define MATH_UTILS_H
#ifdef __cplusplusextern "C" {#endif
int add(int a, int b);int multiply(int a, int b);
#ifdef __cplusplus}#endif
#endif // MATH_UTILS_HSuch a file can be included in both .c and .cpp files. If you named it math_utils.hpp, a C programmer might get confused: "Is this really for me?"
When to use .hpp?
Here it's the opposite: .hpp is the choice of the modern C++ programmer. Especially if:
- You write only in C++. There is no C in the project and never will be.
- You use templates, STL, exceptions. These are purely C++ features, and the
.hppextension emphasizes that. - You want to explicitly separate C++ code from C. In mixed projects, this prevents confusion.
- You follow modern practices. Boost, Qt (partially), and many new libraries use
.hpp.
Example: a typical C++ header with a class
// player.hpp#ifndef PLAYER_HPP#define PLAYER_HPP
#include <string>#include <vector>
class Player {public: Player(const std::string& nam