Preprocessor directives are lines included in the code of programs preceded by a hash sign (#
). These lines are not program statements but directives for the preprocessor.
marcro definitions (#define, #undef)
To define preprocessor macros we can use #define
. Its syntax is:#define identifier replacement
#define
can work also with parameters to define function macros:#define getmax(a,b) a>b?a:b
Defined macros are not affected by block structure. A macro lasts until it is undefined with the #undef
preprocessor directive.
Function macro definitions accept two special operators (#
and ##
) in the replacement sequence:
The operator #
, followed by a parameter name, is replaced by a string literal that contains the argument passed (as if enclosed between double quotes).
The operator ##
concatenates two arguments leaving no blank spaces between them.
Because preprocessor replacements happen before any C++ syntax check, macro definitions can be a tricky feature. But, be careful: code that relies heavily on complicated macros become less readable, since the syntax expected is on many occasions different from the normal expressions programmers expect in C++.
Conditional inclusions (#ifdef, #ifndef, #if, #endif, #else, #elif)
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. #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.
The #if
, #else
and #elif
(i.e., “else if”) directives serve to specify some condition to be met in order for the portion of code they surround to be compiled. The condition that follows #if
or #elif
can only evaluate constant expressions, including macro expressions.
Line control (#line)
The #line
directive allows us to control both things, the line numbers within the code files as well as the file name that we want that appears when an error takes place.
Error directive (#error)
This directive aborts the compilation process when it is found, generating a compilation error that can be specified as its parameter.
Source file inclusion (#include)
#include <header>
#include "file"
Pragma directive (#pragma)
This directive is used to specify diverse options to the compiler. These options are specific for the platform and the compiler you use. Consult the manual or the reference of your compiler for more information on the possible parameters that you can define with #pragma
.
Predefined macro names
The following macro names are always defined (they all begin and end with two underscore characters, __):
macro | value |
---|---|
__LINE__ |
Integer value representing the current line in the source code file being compiled. |
__FILE__ |
A string literal containing the presumed name of the source file being compiled. |
__DATE__ |
A string literal in the form “Mmm dd yyyy” containing the date in which the compilation process began. |
__TIME__ |
A string literal in the form “hh:mm:ss” containing the time at which the compilation process began. |
__cplusplus |
An integer value. All C++ compilers have this constant defined to some value. Its value depends on the version of the standard supported by the compiler: - 199711L : ISO C++ 1998/2003- 201103L : ISO C++ 2011Non conforming compilers define this constant as some value at most five digits long. Note that many compilers are not fully conforming and thus will have this constant defined as neither of the values above. |
__STDC_HOSTED__ |
1 if the implementation is a hosted implementation (with all standard headers available)0 otherwise. |
The following macros are optionally defined, generally depending on whether a feature is available:
macro | value |
---|---|
__STDC__ |
In C: if defined to 1 , the implementation conforms to the C standard.In C++: Implementation defined. |
__STDC_VERSION__ |
In C: - 199401L : ISO C 1990, Ammendment 1- 199901L : ISO C 1999- 201112L : ISO C 2011In C++: Implementation defined. |
__STDC_MB_MIGHT_NEQ_WC__ |
1 if multibyte encoding might give a character a different value in character literals |
__STDC_ISO_10646__ |
A value in the form yyyymmL , specifying the date of the Unicode standard followed by the encoding of wchar_t characters |
__STDCPP_STRICT_POINTER_SAFETY__ |
1 if the implementation has strict pointer safety (see [get_pointer_safety](https://www.cplusplus.com/get_pointer_safety) ) |
__STDCPP_THREADS__ |
1 if the program can have more than one thread |