#include, #define and include guards
The header config.h defines the constant constexpr int kMaxUsers = 100;. The header users.h includes config.h, and main.cpp includes both—and does not compile:
#include "config.h"
#include "users.h" // ✗
int main() {
return kMaxUsers;
}error: redefinition of 'kMaxUsers'The preprocessor
Before the compiler sees a file, the preprocessor reads it and carries out its directives—lines that start with #. The #include directive replaces itself with the text of the named file, word for word, checking nothing in it. The text of config.h reaches main.cpp twice: directly and through users.h. The translation unit ends up with two definitions of kMaxUsers, and the compiler rejects them.
Macros
The #define directive creates a macro—a name that the preprocessor replaces with the given text. A macro can stand for a constant, or it can take parameters like a function:
#include <iostream>
#define MAX_USERS 100
#define SQUARE(x) x * x
int main() {
std::cout << MAX_USERS << ' ' << SQUARE(7) << '\n'; // 100 49
}What reaches the compiler is already 100 and 7 * 7. The preprocessor does not evaluate a macro's argument. It pastes the argument's text in place of x as is and adds no parentheses. The compiler then evaluates the resulting expression with the usual operator precedence.
Macro names are written in all caps so that nobody mistakes them for variables and functions. For constants, constexpr variables are used instead of macros: they have a type, and the compiler checks them.
Include guards
An include guard keeps a header's text from entering a translation unit twice. Its shortest form is the line #pragma once at the top of the header:
#pragma once
constexpr int kMaxUsers = 100;When #include meets this file in the same translation unit a second time, the preprocessor skips it. #pragma once is not part of the C++ standard, but GCC, Clang and MSVC all support it. The standard form is three directives: #ifndef CONFIG_H and #define CONFIG_H at the top of the file and #endif at the end. On the first include CONFIG_H does not exist yet and the text goes through; on the second, #ifndef skips to #endif.
The guard works within one translation unit. Every other .cpp file that includes the header gets its own copy of its text.
Common mistake
The macro halves its argument, but the result is wrong:
#include <iostream>
#define HALF(x) x / 2
int main() {
int result = HALF(10 + 4); // ✗
std::cout << result << '\n'; // 12
}Neither the compiler nor the program reports an error. The preprocessor turned HALF(10 + 4) into 10 + 4 / 2, and division comes before addition.
Write a function instead of such a macro: constexpr int half(int x) { return x / 2; }. A function receives its argument already computed—14. With constexpr, a call with a constant argument can also initialize a constexpr variable. A call used that way must be computed at compile time.