0% found this document useful (0 votes)
19 views

Chapter 17 Preprocessor Directives

The document discusses preprocessor directives in C programming. It describes various preprocessor directives like #define, #include, #undef, #line, #pragma and conditional directives #if, #ifdef, #ifndef, #else, #elif and #endif. It explains their syntax and usage along with examples.
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

Chapter 17 Preprocessor Directives

The document discusses preprocessor directives in C programming. It describes various preprocessor directives like #define, #include, #undef, #line, #pragma and conditional directives #if, #ifdef, #ifndef, #else, #elif and #endif. It explains their syntax and usage along with examples.
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 13

Computer

Fundamentals and
Programming in C
2nd Edition
Reema Thareja

1
© Oxford University Press 2016. All rights reserved.
CHAPTER 17
REPROCESSOR DIRECTIVE

© Oxford University Press 2016. All rights reserved.


INTRODUCTION
• The preprocessor is a program that processes the source code before it passes through the compiler. It
operates under the control of preprocessor directive which is placed in the source program before the
main().
• Before the source code is passed through the compiler, it is examined by the preprocessor for any
preprocessor directives. In case, the program has some preprocessor directives, appropriate actions are
taken (and the source program is handed over to the compiler.
• The preprocessor directives are always preceded by a hash sign (#).
• The preprocessor is executed before the actual compilation of program code begins. Therefore, the
preprocessor expands all the directives and take the corresponding actions before any code is generated
by the program statements.
• No semicolon (;) can be placed at the end of a preprocessor directive.
The advantages of using preprocessor directives in a C program include:
• Program becomes readable and easy to understand
• Program can be easily modified or updated
• Program becomes portable as preprocessor directives makes it easy to compile the program in different
execution environments
• Due to the aforesaid reason the program also becomes more efficient to use.

© Oxford University Press 2016. All rights reserved.


TYPES OF PREPROCESSOR DIRECTIVES
Preprocessor Directive

Unconditional Conditional

define line undef include error pragma if else elif ifdef ifndef endif

• #define
• To define preprocessor macros we use #define. The #define statement is also known as macro definition
or simply a macro. There are two types of macros- object like macro and function like macro.

Object like macro


• An object-like macro is a simple identifier which will be replaced by a code fragment. They are usually
used to give symbolic names to numeric constants. Object like macros do not take ant argument. It is the
same what we have been using to declare constants using #define directive. The general syntax of
defining a macro can be given as:
• #define identifier string
• The preprocessor replaces every occurrence of the identifier in the source code by a string.
• #define PI 3.14

© Oxford University Press 2016. All rights reserved.


Function-like macros
• They are used to stimulate functions.
• When a function is stimulated using a macro, the macro definition replaces the function definition.
• The name of the macro serves as the header and the macro body serves as the function body. The name
of the macro will then be used to replace the function call.
• The function-like macro includes a list of parameters.
• References to such macros look like function calls. However, when a macro is referenced, source code is
inserted into the program at compile time. The parameters are replaced by the corresponding
arguments, and the text is inserted into the program stream. Therefore, macros are considered to be
much more efficient than functions as they avoid the overhead involved in calling a function.
• The syntax of defining a function like macro can be given as
• # define identifier(arg1,arg2,...argn) string
• The following line defines the macro MUL as having two parameters a and b and the replacement string
(a * b):
• #define MUL(a,b) (a*b)
• Look how the preprocessor changes the following statement provided it appears after the macro
definition.
• int a=2, b=3,c;
• c = MUL(a,b);

© Oxford University Press 2016. All rights reserved.


OPERATORS RELATED TO MACROS
# Operator to Convert to String Literals
• The # preprocessor operator which can be used only in a function like macro definition is used to convert the
argument that follows it to a string literal. For example:
• #include<stdio.h>
• #define PRINT(num) printf( #num " = %d", num)
• main()
• {
• PRINT(20);
• } The macro call expands to
• printf( “num" “ = %d", num)
• Finally, the preprocessor will automatically concatenate two string literals into one string. So the above
statement will become
• printf( “num = %d", num)

Merge Operator (##)


• At times you need macros to generate new tokens. Using the merge operator you can concatenate two tokens
into a third valid token. For example,
• #include<stdio.h>
• #define JOIN(A,B) A##B
• main()
• {
• int i;
• for(i=1;i<=5;i++)
• printf("\n HI JOIN(USER, i) : ");
• }
• The above program would print
• HI USER1
• HI USER2
• HI USER3
• HI USER4
• HI USER5

© Oxford University Press 2016. All rights reserved.


#include
• An external file containing function, variables or macro definitions can be included as a part of our
program. This avoids the effort to re-write the code that is already written.
• The #include directive is used to inform the preprocessor to treat the contents of a specified file as if
those contents had appeared in the source program at the point where the directive appears.
• The #include directive can be used in two forms. Both forms makes the preprocessor insert the entire
contents of the specified file into the source code of our program. However, the difference between the
two is the way in which they search for the specified.
#include <filename>
• This variant is used for system header files. When we include a file using angular brackets, a search is
made for the file named filename in a standard list of system directories.
#include "filename"
• This variant is used for header files of your own program. When we include a file using double quotes,
the preprocessor searches the file named filename first in the directory containing the current file, then
in the quote directories and then the same directories used for <filename>.

#undef
• As the name suggests, the #undef directive undefines or removes a macro name previously created with
#define. Undefining a macro means to cancel its definition. This is done by writing #undef followed by
the macro name that has to be undefined.

© Oxford University Press 2016. All rights reserved.


#line
• Compile the following C program.
• #include<stdio.h>
• main()
• { int a=10:
• printf("%d", a);
• }
• The above program has a compile time error because instead of a semi-colon there is a colon that ends
line int a = 10. So when you compile this program an error is generated during the compiling process and
the compiler will show an error message with references to the name of the file where the error
happened and a line number. This makes it easy to detect the erroneous code and rectify it.
• The #line directive enables the users to control the line numbers within the code files as well as the file
name that we want that appears when an error takes place. The syntax of #line directive is:
• #line line_number filename
• Here, line_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 redefines the file name that will appear in case an error occurs.
The filename must be enclosed within double quotes. If no filename is specified then the compiler will
show the original file name. For example:
• #include<stdio.h>
• main()
• { #line 10 "Error.C"
• int a=10:
• #line 20
• printf("%d, a);
• }

© Oxford University Press 2016. All rights reserved.


PRAGMA DIRECTIVES
• The #pragma directive is used to control the actions of the compiler in a particular portion of a program
without affecting the program as a whole.
• The effect of pragma will be applied from the point where it is included to the end of the compilation
unit or until another pragma changes its status.
• A #pragma directive is an instruction to the compiler and is usually ignored during preprocessing. The
syntax of using a pragma directive can be given as:
• #pragma string

INSTRUCTION DESCRIPTION
COPYRIGHT To specify a copyright string
COPYRIGHT_DATE To specify a copyright date for the copyright string
HP_SHLIB_VERSION To create versions of a shared library routine
LOCALITY To name a code subspace
OPTIMIZE To turn the optimization feature on or off
OPT_LEVEL To set the level of optimization
VERSIONID To specify a version string

© Oxford University Press 2016. All rights reserved.


CONDITIONAL DIRECTIVES
• A conditional directive is used instruct the preprocessor to select whether or not to include a chunk of code in the
final token stream passed to the compiler. The preprocessor conditional directives can test arithmetic expressions,
or whether a name is defined as a macro, etc.
• Conditional preprocessor directives can be used in the following situations:
• A program may need to use different code depending on the machine or operating system it is to run on.
• The conditional preprocessor directive is very useful when you want to compile the same source file into two
different programs. While one program might make frequent time-consuming consistency checks on its
intermediate data, or print the values of those data for debugging, the other program, on the other hand can avoid
such checks.
• The conditional preprocessor directives can be used to exclude code from the program whose condition is always
false but is needed to keep it as a sort of comment for future reference.
#ifdef
• #ifdef is the simplest sort of conditional preprocessor directive and is used to check for the existence of macro
definitions. Its syntax can be given as:
• #ifdef MACRO
• controlled text
• #endif
• #ifdef MAX
• int STACK[MAX];
• #endif

© Oxford University Press 2016. All rights reserved.


#ifndef
The #ifndef directive is the opposite of #ifdef directive. It checks whether the MACRO has not been
defined or if its definition has been removed with #undef.
#ifndef is successful and returns a non-zero value if the MACRO has not been defined. Otherwise in case
of failure, that is when the MACRO has already been defined, #ifndef returns false (0).
• The general format to use #ifndef is the same as for #ifdef:
• #ifndef MACRO
• controlled text
• #endif

The #if Directive


• The #if directive is used to control the compilation of portions of a source file. If the specified condition
(after the #if) has a nonzero value, the controlled text immediately following the #if directive is retained
in the translation unit.
• The #if directive in its simplest form consists of
• #if condition
controlled text
#endif
• While using #if directive, make sure that each #if directive 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. However, the #else directive (if present) must be the last directive before #endif.

© Oxford University Press 2016. All rights reserved.


The #else Directive
•The #else directive can be used within the controlled text of an #if directive to provide alternative text to be
used if the condition is false. The general format of #else directive can be given as:
#if condition
Controlled text1
#else
Controlled text2
#endif

The #elif Directive


•The #elif directive is used when there are more than two possible alternatives. The #elif directive like the
#else directive is embedded within the #if directive and has the following syntax:
• #if condition
Controlled text1
#elif new_condition
Controlled text2
#else
Controlled text3
#endif

THE #endif DIRECTIVE


–The general syntax of #endif preprocessor directive which is used to end the conditional compilation
directive can be given as:
#endif

–The #endif directive ends the scope of the #if , #ifdef , #ifndef , #else , or #elif directives.

© Oxford University Press 2016. All rights reserved.


THE defined OPERATOR
We have seen that we can check the existence of a macro by using #ifdef directive. However, the alternative to #ifdef
directive is to use the defined unary operator. The defined operator has one of the following forms:
defined MACROdefined (MACRO)
• The above expression evaluates to 1 if MACRO is defined and to 0 if it is not. The defined operator helps you to check
for macro definitions in one concise line without having to use many #ifdef or #ifndef directives. For example,
• #if defined (MACRO1) && defined (MACRO2)
• Controlled text1
• #else
printf(“\n MACROS not defined”);
#endif
#error DIRECTIVE
• The #error directive is used to produce compiler-time error messages. The syntax of this directive is:
#error string

• The error messages include the argument string. The #error directive is usually used to detect
programmer inconsistencies and violation of constraints during preprocessing.
• When #error directive is encountered, the compilation process terminates and the message specified in
string is printed to stderr. For example,
• #ifndef SQUARE
• #error MACRO not defined.
• #endif
• #ifndef VERSION
#error Version number is not specified.
#endif

© Oxford University Press 2016. All rights reserved.

You might also like