#
). These lines are not program statements but directives for the preprocessor. The preprocessor examines the code before actual compilation of code begins and resolves all these directives before any code is actually generated by regular statements.
These preprocessor directives extend only across a single line of code. As soon as a newline character is found, the preprocessor directive is ends. No semicolon (;
) is expected at the end of a preprocessor directive. The only way a preprocessor directive can extend through more than one line is by preceding the newline character at the end of the line by a backslash (\
).
#define
. Its syntax is:
#define identifier replacement
identifier
in the rest of the code by replacement
. This replacement
can be an expression, a statement, a block or simply anything. The preprocessor does not understand C++ proper, it simply replaces any occurrence of identifier
by replacement
.
1
2
3
#define TABLE_SIZE 100
int table1[TABLE_SIZE];
int table2[TABLE_SIZE];
TABLE_SIZE
, the code becomes equivalent to:
1
2
int table1[100];
int table2[100];
#define
can work also with parameters to define function macros:
1
#define getmax(a,b) a>b?a:b
getmax
followed by two arguments by the replacement expression, but also replacing each argument by its identifier, exactly as you would expect if it was a function:
// function macro
#include <iostream>
using namespace std;
#define getmax(a,b) ((a)>(b)?(a):(b))
int main()
{
int x=5, y;
y= getmax(x,2);
cout << y << endl;
cout << getmax(7,x) << endl;
return 0;
}
5 7
#undef
preprocessor directive:
1
2
3
4
5
#define TABLE_SIZE 100
int table1[TABLE_SIZE];
#undef TABLE_SIZE
#define TABLE_SIZE 200
int table2[TABLE_SIZE];
1
2
int table1[100];
int table2[200];
#
and ##
) in the replacement sequence:
#
, followed by a parameter name, is replaced by a string literal that contains the argument passed (as if enclosed between double quotes):
1
2
#define str(x) #x
cout << str(test);
##
concatenates two arguments leaving no blank spaces between them:
1
2
#define glue(a,b) a ## b
glue(c,out) << "test";
#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:
1
2
3
#ifdef TABLE_SIZE
int table[TABLE_SIZE];
#endif
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:
1
2
3
4
#ifndef TABLE_SIZE
#define TABLE_SIZE 100
#endif
int table[TABLE_SIZE];
TABLE_SIZE
macro has not been defined yet, it would be defined to a value of 100. If it already existed it would keep its previous value since the #define
directive would not be executed.
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. For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#if TABLE_SIZE>200
#undef TABLE_SIZE
#define TABLE_SIZE 200
#elif TABLE_SIZE<50
#undef TABLE_SIZE
#define TABLE_SIZE 50
#else
#undef TABLE_SIZE
#define TABLE_SIZE 100
#endif
int table[TABLE_SIZE];
#if
, #elif
and #else
chained directives ends with #endif
.
The behavior of #ifdef
and #ifndef
can also be achieved by using the special operators defined
and !defined
respectively in any #if
or #elif
directive:
1
2
3
4
5
6
7
#if defined ARRAY_SIZE
#define TABLE_SIZE ARRAY_SIZE
#elif !defined BUFFER_SIZE
#define TABLE_SIZE 128
#else
#define TABLE_SIZE BUFFER_SIZE
#endif
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. Its format is:
#line number "filename"
number
is the new line number that will be assigned to the next code line. The line numbers of successive lines will be increased one by one from this point on.
"filename"
is an optional parameter that allows to redefine the file name that will be shown. For example:
1
2
#line 20 "assigning variable"
int a?;
"assigning variable"
, line 20.
1
2
3
#ifndef __cplusplus
#error A C++ compiler is required!
#endif
__cplusplus
is not defined (this macro name is defined by default in all C++ compilers).
#include
directive it replaces it by the entire content of the specified header or file. There are two ways to use #include
:
1
2
#include <header>
#include "file"
<>
. 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 (<>
).
#pragma
.
If the compiler does not support a specific argument for #pragma
, it is ignored - no syntax error is generated.
_
):
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/2003201103L
: ISO C++ 2011__STDC_HOSTED__
1
if the implementation is a hosted implementation (with all standard headers available)
0
otherwise.
__STDC__
In C: if defined to 1
, the implementation conforms to the C standard.
__STDC_VERSION__
In C:
199401L
: ISO C 1990, Ammendment 1199901L
: ISO C 1999201112L
: ISO C 2011__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
) __STDCPP_THREADS__
1
if the program can have more than one thread
For example:
// standard macro names
#include <iostream>
using namespace std;
int main()
{
cout << "This is the line number " << __LINE__;
cout << " of file " << __FILE__ << ".\n";
cout << "Its compilation began " << __DATE__;
cout << " at " << __TIME__ << ".\n";
cout << "The compiler gives a __cplusplus value of " << __cplusplus;
return 0;
}
This is the line number 7 of file /home/jay/stdmacronames.cpp. Its compilation began Nov 1 2005 at 10:12:29. The compiler gives a __cplusplus value of 1
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4