Pre Processor Directives
#include
The #include "file"
looks for file, first in same directory as of the source file.
If the file is not found there, then it is demoted to #include <file>
which looks for the file according to the rules defined by the implementation.
#define
This directive is used to define macros.
Without Arguments
It is used to replace tokens by a replacement test.
#define TOKEN replacement text
Any of the following appearing in source code, won't be replaced
- "TOKEN" (
token
appearing as astring
1) - TOKENIZATION (
token
appear as part of someidentifier
orkeyword
etc)
The replacement text
can be carried to multiple lines by using \
in the end.
#define TEST for (int i = 0; i < 5; i++) {\
printf("hi\n");\
}
int main () {
TEST
return 0;
}
It prints
hi
hi
hi
hi
hi
With Arguments
#define MACRO(arg1, arg2) some replacement text using arg1 and arg2
int main () {
MACRO(1, 2)
}
There are some problems with this though
#define SQUARE1(x) x * x
#define SQUARE2(x) (x) * (x)
int main () {
int x;
int a = SQUARE1(5);
int b = SQUARE1(5 + x);
int c = SQUARE2(5 + x);
}
gcc -E main.c -o main.i
cat main.i
int main () {
int x;
int a = 5 * 5;
int b = 5 + x * 5 + x; // (1)!
int c = (5 + x) * (5 + x);
}
- Problematic!
We can also use #
to have the replacement text wrapped around double quotes.
#define MACRO(x) printf(#x)
int main () {
MACRO(hello world); // (1)!
}
TOKEN(hello world)
will be replaced byprintf("hello world")
.
We can use ##
to concatenate multiple arguments within the replacement text.
#define MACRO1(x, y) x y
#define MACRO2(x, y) x ## y
int main () {
MACRO1(1, 2) // (1)!
MACRO2(1, 2) // (2)!
}
- Gets replaced by
1 2
- Gets replaced by
12
#undef
Removes the definition of a macro which was defined using #define
.
#define MACRO 420
#undef MACRO
int main () {
int x = MACRO; // (1)!
}
- After being pre-processed, the
MACRO
is not replaced by420
#if
Similar to if
statements.
#elif
Similar to else if
statements.
#else
Similar to else
statements.
#endif
Specifies the end of a block defined by #if
and #ifdef
.
#if !defined(HDR) // (1)!
#define HDR
// file content
#endif
defined()
checks if a macro was defined or not.
#ifdef
Both #if defined(MACRO)
and #ifdef MACRO
are same.
#ifndef
Both #if !defined(MACRO)
and #ifndef MACRO
are same.
We can combine all these to conditionally include files too.
#if SYSTEM == SYSV
#define HDR "sysv.h"
#elif SYSTEM == BSD
#define HDR "bsd.h"
#elif SYSTEM == MSDOS
#define HDR "msdos.h"
#else
#define HDR "default.h"
#include HDR // (1)!
- The
HDR
symbol contains the appropriate file as replacement text according to what theSYSTEM
symbol contains and then it is included.