The C
Preprocessor
The C
preprocessor is a macro processor that is used automatically
by the C compiler to transform your program before actual compilation. It is
called a macro processor because it allows you to definemacros, which
are brief abbreviations for longer constructs.
The C
preprocessor provides four separate facilities that you can use as you see fit:
- Inclusion of header files. These
are files of declarations that can be substituted into your program.
- Macro expansion. You can define macros,
which are abbreviations for arbitrary fragments of C code, and then the C
preprocessor will replace the macros with their definitions throughout the
program.
- Conditional compilation. Using
special preprocessing directives, you can include or exclude parts of the
program according to various conditions.
- Line control. If you use a program to combine or rearrange source files into an intermediate file which is then compiled, you can use line control to inform the compiler of where each source line originally came from.
Preprocessing Directives
Preprocessing
directives are lines in your program that start with `#'. The `#' is
followed by an identifier that is the directive name.
SL Number
|
Directive
|
Meaning
|
1
|
# include
|
include a source file
|
2
|
# define
|
define a macro
|
3
|
# undef
|
undefine a macro
|
4
|
# if
|
conditional compilation
|
5
|
# ifdef
|
conditional compilation
|
6
|
# ifndef
|
conditional compilation
|
7
|
# elif
|
conditional compilation
|
8
|
# else
|
conditional compilation
|
9
|
# endif
|
conditional compilation
|
10
|
# line
|
control error reporting
|
11
|
# error
|
force an error message
|
12
|
# pragma
|
used for
implementation-dependent control
|
13
|
#
|
null directive; no effect
|
1. #include
Both user and system header files are
included using the preprocessing directive `#include'. This comes in two flavours:
#include
< stdio.h >
#include
"myheader.h"
both of which cause a new file to be
read at the point where they occur.
The effect
of using brackets <> or quotes " " around
the filename is to change the places searched to find the specified file. <> directives tell the preprocessor to get stdio.h from System
Libraries and add the text to the current source file. The next line
tells preprocessor to get myheader.h from the local directory
and add the content to the current source file. If
the form using " " can't find the file, it tries searching again
from System Libraries.
In general, brackets are
used when you specify standard library header files, quotes are used for
private header files—often specific to one program only.
Once-Only Include Files
Very often, one header file
includes another. It can easily result that a certain header file is included
more than once. This may lead to errors, if the header file defines structure
types or typedefs, and is certainly wasteful. Therefore, we often wish to
prevent multiple inclusion of a header file.
The
standard way to do this is to enclose the entire real contents of the file in a
conditional, like this:
#ifndef FILE_FOO_SEEN
#define FILE_FOO_SEEN
the entire file
#endif /* FILE_FOO_SEEN */
|
2.
# define
The #define creates
a macro. A preprocessor define directive directs
the preprocessor to replace all subsequent occurrences of a macro with
specified replacement tokens. A simple macro is
a kind of abbreviation.
Before
you can use a macro, you must define it explicitly with the `#define' directive. `#define' is
followed by the name of the macro and then the code it should be an
abbreviation for. For example,
#define BUFFER_SIZE 1020
|
defines a
macro named `BUFFER_SIZE' as an abbreviation for the text `1020'. If somewhere after this `#define' directive
there comes a C statement of the form
foo = (char *) xmalloc (BUFFER_SIZE);
|
then the
C preprocessor will recognize and expand the macro `BUFFER_SIZE', resulting in
foo = (char *) xmalloc (1020);
|
3. # undef
The name of any #defined identifier can be forcibly forgotten by saying
#define WIDTH 80
#define ADD( X, Y ) ((X) + (Y))
#undef WIDTH
#undef ADD
To remove a
macro definition using #undef, give only the macro identifier;
do not give a parameter list.
4.
#if, #elif, #else, and #endif
Directives
The #if directive,
with the #elif, #else, and #endif directives,
controls compilation of portions of a source file. Each
#if directive in a source file must be matched by a closing #endif directive.
Any number of #elif directives can appear between the #if and #endif directives,
but at most one #else directive is allowed. The #else directive,
if present, must be the last directive before #endif.
#if
defined(CREDIT)
credit();
#elif
defined(DEBIT)
debit();
#else
printerror();
#endif
Each #if directive
in a source file must be matched by a closing #endif directive.
Any number of #elif directives can appear between the #if and #endif directives,
but at most one #else directive is allowed. The #else directive,
if present, must be the last directive before #endif.
The #if, #elif, #else,
and #endif directives can nest in the text portions of other #if directives.
Each nested #else,#elif, or #endif directive
belongs to the closest preceding #if directive. All
conditional-compilation directives, such as #if and #ifdef,
must be matched with closing #endif directives prior to the
end of file; otherwise, an error message is generated.
#if DLEVEL
> 5
#define SIGNAL 1
#if STACKUSE == 1
#define STACK 200
#else
#define STACK 100
#endif
#else
#define SIGNAL 0
#if STACKUSE == 1
#define STACK 100
#else
#define STACK 50
#endif
#endif
#if DLEVEL
== 0
#define STACK 0
#elif
DLEVEL == 1
#define STACK 100
#elif
DLEVEL > 5
display( debugptr );
#else
#define STACK 200
#endif
The #ifdef and #ifndef directives
perform the same task as the #if directive when it is used ith defined( identifier ).
#ifdef
identifier
#ifndef
identifier
//
equivalent to
#if defined
identifier
#if
!defined identifier
You can use
the #ifdef and #ifndef directives anywhere #if can
be used. The #ifdef identifier statement is
equivalent to #if 1 when identifier has been
defined, and it is equivalent to #if 0 when identifier has
not been defined or has been undefined with the #undef directive.
These directives check only for the presence or absence of identifiers defined
with #define, not for identifiers declared in the C or C++ source
code.
The #ifndef directive
checks for the opposite of the condition checked by #ifdef. If the
identifier has not been defined (or its definition has been removed with #undef),
the condition is true (nonzero). Otherwise, the condition is false (0).
5.
#line
A preprocessor
line control directive supplies line numbers for compiler messages. It
causes the compiler to view the line number of the next source line as the
specified number. You can use #line control
directives to make the compiler provide more meaningful error messages.
/**
** This example illustrates #line directives.
**/
#include
<stdio.h>
#define
LINE200 200
int
main(void)
{
func_1();
func_2();
}
#line 100
func_1()
{
printf("Func_1 - the current line
number is %d\n",_ _LINE_ _);
}
#line
LINE200
func_2()
{
printf("Func_2 - the current line
number is %d\n",_ _LINE_ _);
}
This program produces the following
output:
Func_1 -
the current line number is 102
Func_2 -
the current line number is 202
6.
#error
The #error directive
emits a user-specified error message at compile time and then terminates the
compilation.
#if
!defined(__cplusplus)
#error C++
compiler required.
#endif
7. #pragma
There are many type of pragma directive and varies from one
compiler to another compiler .If compiler does not recognize particular pragma
the it simply ignore that pragma statement without showing any error or warning
message and execute the whole program assuming this pragma statement is not
present. For example
suppose there is any pragma directive is #pragma world .
#include<stdio.h>
#pragma world
int main(){
printf("C is powerful
language ");
return 0;
}
Output : C is powerful language
Since
#pragma world is unknown for Turbo c 3.0 compiler so it will ignore
this directive without showing any error or warning message and execute the
whole program assuming #pragma world statement is not present.
1. #
The null preprocessor directive is a
single number sign (#) alone on a line. It has no effect.
Sources:
No comments:
Post a Comment