File types · Explainer

The C and C++ header file (.h, .hpp)

An H file is a header: a plain-text file of declarations that C and C++ source files include so they can share functions, types and constants. This guide explains what belongs in one, how including works, include guards and #pragma once, the errors people hit most, and has free sample header files to download for testing.

At a glance

Full name
Header file (C, C++ and Objective-C)
Extensions
.h; C++ projects also use .hpp, .hh and .hxx; C++'s own standard headers have none
MIME type
None registered; Linux desktops use text/x-chdr, and text/x-c++hdr for C++ headers
Kind
Plain text (source code), included by other files, never compiled on its own
Standard
The #include mechanism is defined by the C standard (ISO/IEC 9899) and the C++ standard (ISO/IEC 14882)
Used by
C, C++ and Objective-C; also tools that call C libraries from other languages, such as Go's cgo and Rust's bindgen
Opens with
Any text editor or IDE: VS Code, Visual Studio, CLion, Xcode, Vim
Protection against double inclusion
An include guard (#ifndef/#define/#endif) or #pragma once
Magic number
None

The basics

What is an H file?

A .h file is a header file for C or C++ (and Objective-C). It declares what a piece of code offers, such as the functions in a library, their parameters and the types they use, so that other source files can call them. A source file uses a header by including it: #include "geometry.h".

Headers are everywhere in C and C++. stdio.h and stdlib.h come with every C compiler; operating systems ship thousands of them (windows.h, unistd.h); and every library you add brings its own. On Linux and macOS, system headers live in folders such as /usr/include; on Windows, in the Windows SDK and Visual Studio folders.

Three things that clear up common confusion:

  • A header isn't compiled on its own. It's pasted into each .c or .cpp file that includes it, and compiled as part of that file.
  • A header usually has no code that does anything. It describes; the matching .c or .cpp file implements. Header-only libraries, below, are the exception.
  • .h doesn't tell you the language. The same extension is used for C and C++ headers; read the file (or look for .hpp) to know whether it needs a C++ compiler.

Anatomy

What's inside a header file

A header says what exists without, for the most part, saying how it works: types, function prototypes, constants and the occasional small inline function. Here is a typical C header that is also safe to use from C++, part by part.

geometry.h
/* geometry.h: points and the functions that measure them */
#ifndef GEOMETRY_H
#define GEOMETRY_H

#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

#define GEOMETRY_PI 3.14159265358979323846

typedef struct {
    double x, y;
} point;

double distance(point a, point b);
double polygon_area(const point *corners, size_t count);

extern int geometry_calls;

static inline double square(double v)
{
    return v * v;
}

#ifdef __cplusplus
}
#endif

#endif /* GEOMETRY_H */
  1. 1/* geometry.h: … */

    A comment

    Often the documentation for the whole library: the header is the part users read.

  2. 2#ifndef GEOMETRY_H / #define GEOMETRY_H

    The include guard

    The first time the header is included, GEOMETRY_H isn't defined, so the contents are read and the macro is defined. Any later include in the same file skips straight to the final #endif.

  3. 3#include <stddef.h>

    What the header itself needs

    size_t is used below, so the header includes the header that defines it. A good header compiles on its own, whatever was included before it.

  4. 4#ifdef __cplusplus / extern "C" {

    C linkage for C++

    C++ compilers encode parameter types into function names (name mangling); C compilers don't. extern "C" makes C++ code look for the plain C names, so it can link to the compiled C library. __cplusplus is only defined by C++ compilers, so C never sees it.

  5. 5#define GEOMETRY_PI …

    A macro constant

    Prefixed with the library's name, because macros ignore scopes and namespaces and can collide with anyone else's.

  6. 6typedef struct { double x, y; } point;

    A type definition

    Every file that uses point needs to know its layout, so the definition goes in the header. Type definitions are allowed to repeat across files; a function or variable definition isn't.

  7. 7double distance(point a, point b);

    Function declarations

    A prototype: name, parameters and return type, ending in a semicolon instead of a body. The body lives in geometry.c, compiled once.

  8. 8extern int geometry_calls;

    A variable declaration

    extern says the variable is defined somewhere else, in exactly one .c file. Without extern, every file that includes the header would define its own.

  9. 9static inline double square(double v) { … }

    An inline function

    Small functions can be defined in a header if they're static inline (C) or inline (C++). Each including file gets a copy the compiler can inline, with no clash at link time.

  10. 10#endif /* GEOMETRY_H */

    The end of the guard

    Closes the #ifndef. The comment is a habit that makes long headers easier to read.

Under the hood

How #include works: declarations here, definitions there

#include is plain text substitution. Before compiling a source file, the preprocessor replaces the line with the full contents of the header, and repeats that for every header the header includes. The compiler then sees one long file. That's why a header is "compiled" once for every source file that includes it, and why big headers slow builds down.

  • #include <stdio.h> with angle brackets searches the system and compiler include folders.
  • #include "geometry.h" with quotes searches the including file's own folder first, then the same folders as angle brackets.
  • -I path (GCC, Clang) or /I path (MSVC) adds folders to search; this is how a project finds its libraries' headers.

The split between a header and its source file is the split between a declaration (this exists, and here is its type) and a definition (here it is). Every file that calls distance needs the declaration; only one may contain the definition, or the linker sees two copies.

geometry.c, main.c and the build
/* geometry.c: the definitions */
#include <math.h>
#include "geometry.h"

int geometry_calls = 0;

double distance(point a, point b)
{
    geometry_calls++;
    return sqrt(square(b.x - a.x) + square(b.y - a.y));
}
/* … polygon_area … */

/* main.c: a user of the header */
#include <stdio.h>
#include "geometry.h"

int main(void)
{
    point a = {0, 0}, b = {3, 4};
    printf("%g\n", distance(a, b));   /* prints 5 */
    return 0;
}

/* the build: */
/*   cc -c geometry.c                    -> geometry.o, the code      */
/*   cc -c main.c                        -> main.o, calls distance()  */
/*   cc main.o geometry.o -lm -o demo    -> the linker joins them     */
Belongs in the headerBelongs in the .c or .cpp file
Function declarations (prototypes)Function bodies
Type definitions: struct, enum, typedef, classesVariable definitions: int geometry_calls = 0;
extern variable declarationsstatic helpers used only in that file
Macros and constants other files needMacros only that file needs
static inline / inline functions, templates (C++)Large functions, even if called often
#include lines the header itself needsusing namespace …; in C++: never in a header, where it leaks into every includer

Conventions

Include guards vs #pragma once

A header often gets included twice in one source file, usually indirectly: main.c includes shapes.h and geometry.h, and shapes.h includes geometry.h too. Without protection, the second copy redefines point and the build fails with "redefinition of" errors. Every header needs one of these:

parser.h
/* Include guard: standard C and C++, works everywhere */
#ifndef MYLIB_PARSER_H
#define MYLIB_PARSER_H
/* … declarations … */
#endif /* MYLIB_PARSER_H */

/* #pragma once: one line, not in the standard, supported by
   GCC, Clang and MSVC */
#pragma once
/* … declarations … */
Include guard#pragma once
In the C and C++ standardsYesNo, but GCC, Clang and MSVC all support it
LengthThree lines and a unique macro nameOne line
RiskTwo headers that pick the same macro name silently hide each otherCan be fooled when the same file is reached through different paths, such as copies, symbolic links or network drives
Build speedGCC and MSVC recognise the pattern and don't re-read the fileSame

Either works in practice; many projects use #pragma once for new code and guards where portability to unusual compilers matters. Don't use both. For guard names, use the project and file name in capitals (MYLIB_PARSER_H), and don't start them with an underscore followed by a capital letter: such names are reserved for the compiler and standard library.

Related formats

.h vs .hpp, and other header extensions

The compiler doesn't care what an included file is called: #include pastes in any file. Extensions are for people and tools, and editors use them to pick C or C++ highlighting.

ExtensionWhat it is
.hA C header, or a C++ header in projects that use .h for both. Headers meant for both languages use extern "C", as in the anatomy above
.hpp, .hh, .hxxC++ headers: classes, templates and namespaces that a C compiler can't read. Usually paired with .cpp, .cc and .cxx sources
No extension: <vector>, <string>The C++ standard library's own headers. C library headers are available in C++ as <cstdio> as well as <stdio.h>
.inl, .ipp, .tppInline or template code, included at the end of a header to keep the declarations readable
.gch, .pchPrecompiled headers: binary, compiler-specific files that speed up builds. Generated, never edited or shared
.cppm, .ixxC++20 module interfaces, the newer alternative to headers in C++

Packaging

Header-only libraries

Some libraries are nothing but headers: you copy the .h or .hpp file into your project and include it, with no separate library to build or link. Much of the C++ standard library and many popular C++ libraries work this way, because templates must be defined in headers anyway: the compiler needs the full code to generate a version for each type.

  • In C++, functions and variables defined in a header must be inline (or templates, or constexpr). Without it, two .cpp files including the header each define the function and linking fails with "multiple definition".
  • In C, single-file libraries often contain both halves: declarations normally, and the implementation only in the one source file that writes #define LIBNAME_IMPLEMENTATION before the include.
  • The trade-off is build time: every source file that includes the header compiles all of it again. Precompiled headers and C++20 modules exist to reduce that cost.

Troubleshooting

Header errors people hit most, and what they mean

MessageUsual causeFix
fatal error: foo.h: No such file or directoryThe header's folder isn't on the include path, or the library's development files aren't installedAdd -I path/to/include; on Linux install the library's -dev or -devel package
redefinition of 'struct point'The same header included twice without a guardAdd an include guard or #pragma once
multiple definition of 'x' (MSVC: LNK2005)A variable or non-inline function defined in a header included by several source filesDeclare it extern in the header and define it in one source file; or make the function inline (C++) or static inline (C)
unknown type name 'size_t' / 'x' does not name a typeThe header uses something it doesn't include itself, or two headers include each other in a circleMake each header include what it uses; break circles with a forward declaration such as struct node;
undefined reference to 'stats_init(stats_t*)'C++ calling a C library whose header has no extern "C" block. The parameter types in the message show C++ looked for a mangled nameWrap the header's declarations in extern "C", as in the samples
undefined reference to 'distance'The header was included but the source file that defines the function wasn't compiled or linkedAdd the .c or .cpp file, or the library, to the build

Why you don't compile a .h file

Run gcc geometry.h and GCC doesn't build a program: it writes a precompiled header, geometry.h.gch. Build tools compile the .c and .cpp files, and the headers come along through #include. To check that a header is self-contained, compile a source file that includes only that header.

How to

How to open, read and edit a header file

  • Read it: any text editor works, and a browser shows it as text. A library's headers are often its best reference: they list every function with its parameters.
  • Edit it: VS Code, Visual Studio, CLion, Xcode, Vim and Emacs all understand headers. "Go to definition" in an IDE jumps from a declaration in the header to the code in the source file.
  • Find where something is declared: in a terminal, grep -rn "distance(" include/ searches a folder of headers.
  • See what the compiler sees: gcc -E file.c prints a source file after preprocessing, with every header pasted in. Expect it to be thousands of lines long.

Opening a header is safe: it's text, and nothing runs. Headers do become part of whatever is compiled with them, so a header from an untrusted source deserves the same review as any other code you build, including its macros, which can hide code behind innocent-looking names.

Free downloads

Sample header files to download

Free sample header files, with the source files that use them, for testing compilers, IDEs, syntax highlighting and code viewers. They build with GCC and Clang, as C and as C++, with warnings on and none reported. Download all five into one folder to build them.

sample-header.h · 2.6 KBDownloadOpen
Loading…

What's inside sample-header.h

The header is commented: open it in a text editor and each numbered comment marks one of these parts. Its comments also give the build commands that connect it to the other samples.

  1. Comment 1: the include guard

    #ifndef SAMPLE_HEADER_H / #define SAMPLE_HEADER_H. sample-main.c includes the header twice on purpose to show the guard working.

  2. Comment 2: the header's own includes

    stdbool.h and stddef.h, for bool and size_t, so the header compiles whatever was included before it.

  3. Comments 3 and 9: extern "C"

    Opened and closed inside #ifdef __cplusplus, so the C functions link from sample-main.cpp. The build check for these samples confirms that removing it makes the C++ link fail.

  4. Comments 4 and 5: macros and a type

    A version string, a size limit, and a stats_t struct that callers can create as an ordinary local variable.

  5. Comment 6: function declarations

    Five prototypes ending in semicolons. Their bodies are in sample-header.c.

  6. Comment 7: an extern variable

    extern const char stats_library_name[];, defined once in sample-header.c.

  7. Comments 8 and 10: an inline function and the end of the guard

    A static inline function, one of the few function definitions that belongs in a C header, then the closing #endif.

All sample H files

  • Commented C header with an include guard

    sample-header.h · 2.6 KB (2,627 bytes)

    The header of a tiny statistics library: an include guard, its own includes, extern "C" for C++, macros, a struct, prototypes, an extern variable and a static inline function, with numbered comments explaining each part.

    • Checking syntax highlighters and IDEs on headers
    • Teaching what belongs in a header
  • The matching source file

    sample-header.c · 1.5 KB (1,531 bytes)

    The definitions behind sample-header.h: it includes its own header first, defines the extern variable once and implements the five functions.

    • Showing how a header and its source file pair up
    • Building the C and C++ examples
  • C program that uses the header

    sample-main.c · 950 bytes

    Includes the header twice to show the guard working, then calls the library. Build: cc -std=c17 sample-main.c sample-header.c -o stats-c.

    • A two-file C build test
    • Include-guard demonstration
  • C++ program that uses both headers

    sample-main.cpp · 1.3 KB (1,331 bytes)

    Calls the C library through its extern "C" header, linked against sample-header.o compiled by a C compiler, and uses the header-only C++ library to draw a text bar chart.

    • Testing mixed C and C++ builds
    • Checking that `extern "C"` linkage works with your toolchain
  • Header-only C++ library (#pragma once)

    sample-header-only.hpp · 1.5 KB (1,545 bytes)

    A .hpp header guarded with #pragma once, containing a function template, an inline function and an inline constexpr variable: everything a header-only library needs, with comments on why each is allowed in a header.

    • Comparing `#pragma once` with include guards
    • Testing tools that treat `.hpp` differently from `.h`

Ways to test with them

  • Mixed C and C++ builds: compile sample-header.c with a C compiler and link it into sample-main.cpp with a C++ compiler, as the comments describe. If linking fails, check that both compilers are from compatible toolchains.
  • Self-contained headers: compile a file containing only #include "sample-header.h" as C and as C++; it should produce no errors or warnings.
  • Syntax highlighting: open sample-header.h and sample-header-only.hpp in your viewer; a .h file can be C or C++, so check which highlighting it picks.
  • Upload filters: some systems block or rename source files. Try the samples to see whether .h, .hpp and .c files pass through unchanged.

Free to use for testing, teaching and demos, commercially or not, with no attribution needed. A link back to this page is always appreciated.

Put it online

Have a header file? Give it a link.

Drop a .h file on 99helpers and it gets its own web address. Anyone who opens the link reads it as plain text in their browser: it is never compiled or run, which makes it an easy way to share an API or a library's declarations for review.

Questions

H files, frequently asked

What is a .h file?

A header file for C or C++. It declares functions, types and constants so that .c and .cpp files can include it with #include and use them.

How do I open an H file?

With any text editor or code editor, such as VS Code, Notepad, Visual Studio or Xcode. It's plain text.

Can I run or compile a .h file?

No. A header isn't a program and isn't compiled on its own: you compile the .c or .cpp files that include it. Passing a header straight to GCC makes a precompiled header (.gch), not a program.

What's the difference between .h and .c files?

The .h file declares what exists (function prototypes, types, constants); the .c file defines it (the function bodies). Other files include the .h and are linked with the compiled .c.

What's the difference between .h and .hpp?

Only convention. .hpp signals a C++-only header; .h is used for C headers and, in many projects, for C++ headers too. Compilers treat them the same way when they're included.

Should I use #pragma once or include guards?

Either. Include guards are standard and work everywhere; #pragma once is shorter and supported by GCC, Clang and MSVC, but isn't part of the C or C++ standard. Pick one per project.

What is a header-only library?

A library delivered entirely as header files: you include it and there's nothing separate to build or link. Common in C++, where templates have to be defined in headers anyway.

Why do I get "multiple definition" errors from a header?

Something is defined, not just declared, in a header that several source files include. Declare variables extern in the header and define them in one source file; make header functions inline (C++) or static inline (C).

Related formats

Other file types explained

Keep going

Related

Sources

Last reviewed 27 October 2026.