Question
In C++, I have usually used .h files for class declarations and other header content. However, after looking through some Boost library code, I noticed that many headers use the .hpp extension instead.
What are the practical advantages and disadvantages of using .hpp instead of .h for C++ header files?
Short Answer
By the end of this page, you will understand that .h and .hpp are both header file extensions commonly used in C++, but the main difference is convention rather than language behavior. You will learn how compilers and build tools treat header files, why teams choose one extension over another, and how to pick a consistent convention for your own projects.
Concept
In C++, a header file usually contains declarations such as:
- class declarations
- function declarations
- templates
- inline functions
- constants and macros
- include guards or
#pragma once
The key idea is this:
- C++ itself does not require
.hor.hpp - The file extension is mostly a naming convention
- What matters is how the file is included and how your toolchain treats it
For example, these are both valid includes:
#include "person.h"
#include "person.hpp"
The C++ language does not assign different meaning to them. A header named person.h can contain C++ classes, templates, and namespaces. A header named person.hpp can contain the same things.
So why do both exist?
Why teams use different extensions
Historically:
.hhas long been used for C and C++ headers.hppbecame popular as a way to signal
Mental Model
Think of .h and .hpp like two labels on the same type of folder.
- The folder contents are what matter
- The label helps humans understand what to expect
If you label a folder .h, people may think, "general header" or sometimes "possibly C-style header."
If you label it .hpp, people may think, "this is definitely meant for C++."
The compiler, however, mostly cares about the contents and how the file is used, not the label on the folder.
Syntax and Examples
A header file can use either extension.
Example using .h
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
int add(int a, int b);
#endif
// main.cpp
#include "math_utils.h"
#include <iostream>
int add(int a, int b) {
return a + b;
}
int main() {
std::cout << add(2, 3) << '\n';
}
Example using .hpp
// math_utils.hpp
;
Step by Step Execution
Consider this small example:
// user.hpp
#ifndef USER_HPP
#define USER_HPP
class User {
public:
User(const char* name);
const char* getName() const;
private:
const char* name;
};
#endif
// main.cpp
#include "user.hpp"
#include <iostream>
User::User(const char* name) : name(name) {}
const char* User::getName() const {
return name;
}
int main() {
User user;
std::cout << user.() << ;
}
Real World Use Cases
Here are practical situations where the choice matters.
1. Mixed C and C++ codebases
A project may have:
network.hfor C-compatible declarationsserializer.hppfor C++ classes and templates
This makes the project easier to scan.
2. Library design
Some C++ libraries use .hpp to clearly signal that the headers contain:
- templates
- namespaces
- classes
- overloaded functions
This can be useful for users browsing the API.
3. Legacy systems
Older projects often use .h for everything because that has been a long-standing convention.
4. Build and tooling conventions
Some editors, code generators, or linting setups may group files by extension. A team might choose .hpp if it helps tooling recognize C++ headers more clearly.
5. Team style guides
Many teams pick one rule simply to avoid debates. That is often the most valuable benefit.
Real Codebase Usage
In real projects, developers usually treat this as a style and organization decision.
Common team patterns
Pattern 1: Use .h for all headers
This is common when:
- the codebase is entirely C++
- the team prefers shorter names
- there is no need to distinguish C from C++ headers
Example structure:
include/
user.h
order.h
config.h
src/
user.cpp
order.cpp
Pattern 2: Use .h for C headers and .hpp for C++ headers
This is common when:
- the project mixes C and C++
- a library exposes both C and C++ APIs
- the team wants visual separation
Example structure:
include/
c_api.h
cpp_wrapper.hpp
Pattern 3: Follow the existing ecosystem
If you contribute to an existing project, the normal practice is:
- keep the current naming convention
- avoid renaming files without a strong reason
- prefer consistency over personal preference
Related patterns in real code
Include guards
Regardless of extension, headers should protect against multiple inclusion:
Common Mistakes
1. Thinking .hpp changes compilation behavior
It usually does not.
Broken assumption:
// This is not automatically "more C++" just because of the extension.
#include "widget.hpp"
The compiler does not give special language meaning to .hpp in normal C++ source inclusion.
2. Mixing conventions randomly
Bad example:
user.h
order.hpp
config.hh
math.hxx
If there is no clear reason, this makes the codebase harder to navigate.
Better approach
Pick one convention and document it.
3. Forgetting to update includes after renaming
Broken code:
#include "person.h"
If the file was renamed to person.hpp, this include will fail.
Fixed version:
#include "person.hpp"
Comparisons
.h vs .hpp
| Aspect | .h | .hpp |
|---|---|---|
| Language meaning in C++ | No special difference | No special difference |
| Common interpretation | General header, sometimes C-style | C++ header |
| Historical usage | Very common | Common in C++ projects |
| Mixed C/C++ projects | Can be ambiguous | Helps signal C++ |
| Brevity | Shorter | Slightly more explicit |
| Team consistency value | High if used consistently | High if used consistently |
Other related extensions
Cheat Sheet
Quick facts
.hand.hppare both valid for C++ headers- The extension is mostly a convention
- C++ does not assign different semantics to them
- Consistency matters more than the specific choice
Common meanings
.h= general header.hpp= C++ header
Use .hpp when
- you want to clearly mark files as C++ headers
- your project mixes C and C++
- your team already uses
.hpp
Use .h when
- your codebase already uses
.h - the project is fully C++ and there is no ambiguity
- you prefer the shorter, traditional extension
Always remember
#include "file.h"
#include "file.hpp"
The important difference is the filename, not the C++ language behavior.
Best practice
FAQ
Is .hpp required for C++ headers?
No. C++ does not require .hpp. .h works as well.
Is .h only for C and .hpp only for C++?
No. That is a convention some teams use, not a language rule.
Do compilers treat .h and .hpp differently?
Usually not for included headers. The content and build configuration matter more than the extension.
Why do some libraries use .hpp?
Often to clearly signal that the header is intended for C++ and may contain classes, templates, and namespaces.
Should I rename all my .h files to .hpp?
Usually no, unless your team has a clear reason. Renaming creates churn and may break includes or tooling.
What is the best extension for a new C++ project?
There is no single best choice. Pick a convention that fits your project and use it consistently.
Can a .h file contain templates and classes?
Yes. A .h file can contain any valid C++ header content.
Mini Project
Description
Create a small C++ project with a header and source file, then try the same project using both .h and .hpp. This demonstrates that the extension is a convention and helps you practice file organization, includes, and header protection.
Goal
Build a tiny class-based C++ program and verify that it works the same whether the header uses .h or .hpp.
Requirements
- Create a header file that declares a simple class
- Create a
.cppfile that defines the class methods - Include the header from
main.cpp - Add include guards or
#pragma once - Run the program and confirm it behaves the same after renaming the header extension
Keep learning
Related questions
Advantages of Brace Initialization in C++
Learn why C++ brace initialization is often clearer and safer than other object initialization styles, with examples and common pitfalls.
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Aggregates, Trivial Types, Trivially Copyable Types, and PODs Explained
Learn what aggregates, trivial types, trivially copyable types, and PODs mean in C++, how they differ, and why they matter.