Preprocessor Directives
A preprocessor directive are lines in the code that begin with a hash #
,
and are evaluated by the C++ preprocessor before compilation time.
Commonly used categories include things like macro definitions, conditional inclusions, pragma directives, and source file inclusions.
Conditional Inclusions
These directives allow to include or discard part of the code of a program if a certain condition is met.
#ifdef
allows a section of a program to be compiled only if the macro that is specified as the parameter has been defined, no matter which its value is. For example:
#ifdef TABLE_SIZE
int table[TABLE_SIZE];
#endif
In this case, the line of code int table[TABLE_SIZE];
is only compiled if TABLE_SIZE
was previously defined with #define
, independently of its value. If it was not defined, that line will not be included in the program compilation.
#ifndef
serves for the exact opposite: the code between #ifndef
and #endif
directives is only compiled if the specified identifier has not been previously defined. For example:
#ifndef TABLE_SIZE
#define TABLE_SIZE 100
#endif
int table[TABLE_SIZE];
Source File Inclusion
The #include
directive is used to replace the #include
line with the entirety
of the source file specified.
There are two ways to #include
a header file:
#include <header>
#include "file"
In the first case, a header is specified between angle-brackets <>
. This is used to include headers provided by the implementation, such as the headers that compose the standard library (iostream
, string
, …). Whether the headers are actually files or exist in some other form is implementation-defined, but in any case they shall be properly included with this directive.
The syntax used in the second #include
uses quotes, and includes a file. The file is searched for in an implementation-defined manner, which generally includes the current path. In the case that the file is not found, the compiler interprets the directive as a header inclusion, just as if the quotes (""
) were replaced by angle-brackets (<>
).
Macros
You can define macros to do things like logging, similar to aliases in bash. The compiler will replace these instances in the code with whatever you defined in the macro.
#define LOG(x) std::cout << x << std::endl
// Then, use it in code
int myvar = 3;
LOG(myvar);
You can also just define global constants with #define
:
#define BEGIN 0
#define END 10
for (int i = BEGIN; i < END; i++) {
// do something
}
Pragma Directive
The #pragma once
directive ensures that a header file is only included once in the translation unit during compilation.
When you include this at the top of your header file, it provides include guards that prevent the file from being included multiple times in the same place.