Directives are instructions we can provide for the C++ compiler for a variety of purposes. These are not actual C++ code. They can be recognized easily by the fact that they all start with '#'.
These were inherited by C++ from the C language.
Some commonly used directives
#include <filename>
Include the text of the indicated file at this point; search standard libraries for for the file.
#include "filename"
Include the text of the indicated file at this point; search the current directory as well as standard libraries for the file.
#define NAME value
Associate NAME with the (constant) value (as a string). Before compiling, a search-and-replace operation will replace each occurrence of NAME by the value.
If no value is provided, NAME is a defined symbol with an empty string as its value.
#undef NAME
Removes NAME from the list of defined symbols.
#if expression
If the expression (which must evaluate to a constant value) is not 0, start including lines until #else or #endif is found. If it is 0, skip text until #else or #endif is found.
#ifdef NAME
If NAME is a defined symbol (at this point), start including text until #else or #endif is found.
#ifndef NAME
If NAME is not a defined symbol (at this point), start including text until #else or #endif is found.
#else
See #if, #ifdef and #ifndef above; we have an if-else-endif structure. The body of either part of the structure might be empty.
#endif
Delimiter for the scope of a #if, #ifdef, #ifndef or #else.
defined(NAME)
Used in an #if, this returns 0 if NAME is not a defined symbol and 1 if it is a defined symbol. Thus "#ifdef NAME" is equivalent to "#if defined(NAME)".
There are a few other directives as well, such as #pragma and #elif, which are a bit more obscure.
Expressions
It is possible to use arithmetic expressions in a #define, such as:
#define RECORDSIZE 120 #define BLOCKSIZE (32*RECORDSIZE)
It is possible to use logical expressions in a #if, such as: #if defined(NAME1) && !defined(NAME2)
The expressions will be evaluated when the expanded code is evalauted. Thus, in the above example, BLOCKSIZE is replaced with "(32*120)" rather than with "(3840)".
Macros
It is also possible to use #define to create macros, which can have parameters and which will generate actual C++ code.
Writing macros is somewhat of an art, as it can be difficult to anticipate how the macro may be used.
Here is a (traditional) example:
#define SQUARE(x) x * x
As long as the value supplied for x is just one term, this may work well. However, if someone uses it like this:
SQUARE(a + b)
the result will be
a + b * a + b
rather than
(a + b) * (a + b)
One way to fix this is:
#define SQUARE(x) (x) * (x)
A similar problem occurs with SQUARE(N++), and the above fix will probably not help.
There are some predefined macros required by the ANSI standard, such as:
_DATE_
The value returned is the compilation date as a string of the form "Mmm dd yyyy", where Mmm is a standard 3-letter abbreviation for a month name.
_TIME_
The value returned is the time of compilation as a string of the form "hh:mm:ss" (using a 24-hour clock).
_FILE_
The value returned is as string containing the name of the source code file.
Here is an example of using these:
cout << "File " << _FILE_ << " was compiled at " << _TIME_ << " on " << _DATE_;
There are a few others, and specific compilers frequently provide more predefined macros as well.