The preprocessor is old, primitive, and strong. But you need to understand its strengths to use it effectively. It adds capabilities that the C++ compiler can’t come close to duplicating on its own.

All the preprocessor directives begin with the hash character, #, and do not use a semicolon at the end. The end of a directive is just the end of the line. You can extend a preprocessor directive to other lines by ending each line to be extended with a backslash character, \.

The using statement is the most common preprocessor directive and might look like this:

#include <iostream>
#include "../OtherProject/CustomClass.h"

You’ll also often find conditional sections like this:

#ifndef __cplusplus
#error You must compile this code with a C++ compiler
#endif

A very common pragma directive that allows you to specify that an include file should be processed only once no matter how many times it gets included in a particular compilation unit is:

#pragma once

And you can also use preprocessor directives to define elaborate replacement text like this:

#define MYCLASS(name, id) class name ## id { };

Using this macro like this:

MYCLASS(MyClass, A)

Would be equivalent to writing the following:

class MyClassA { };

This macro not only replaced MYCLASS with the content of the macro but the ## symbols caused the text passed as name and id to be concatenated to form the class name.