SlideShare a Scribd company logo
ANSI C Macros – The C Preprocessor
S.SRIKRISHNAN
PRE - FINAL YEAR
SSN COLLEGE OF ENGINEERING
ne of the features not included in the original C language was the concept of
constants. In order to accommodate various features, (including constants),
the authors of C developed the C preprocessor. None of the services provided
by the C preprocessor (cpp) is indispensible for writing C programs, but these services
make the task considerably easier.
Outline:
1. How the preprocessor works
2. The #define Directive
3. Constants
4. Macros
5. Macros with Arguments
6. The #undef Directive
7. The #include Directive
8. Conditional compilation : #ifdef, #ifndef, #endif
9. Conditional compilation : #if, #else
10.Predefined Macros
O
How The Preprocessor Works
 When you issue the command to compile a C program, the program is run
automatically through the preprocessor
 The preprocessor is a program that modifies the C source program according
to the directives supplied in the program.
 The preprocessor does not modify the program file, but creates a new file that
contains the processed version of the program.
 This new file is then submitted to the compiler.
Fig(a) The Compilation Process
If a program contains the directive
#define NULL 0,
and the statement
x = NULL;
the preprocessor replaces every occurrence of NULL following the #define directive
with 0.
The resulting program no longer includes the directive (since the directives are
only for the preprocessor, not the compiler), and the preceding statement now reads
as follows:
x = 0;
Constants, therefore, are abbreviations supplied for the convenience of the
programmer. Each occurrence of a constant is translated by the preprocessor so that
the program is comprehensible to the C compiler. The preprocessor can also delete or
add C program statements.
Note:
 All preprocessor directives begin with the number or sharp sign (#).
 The directive is terminated not by a semicolon, but by the end of the line on
which it appears.
 Only one directive can occur on a line.
 A preprocessor symbol is never replaced if it occurs within single or double
quotation marks.
 The preprocessor does not check for normal C syntax, except for identifying
quotation marks. It merely substitutes symbols where it finds them.
The #define Directive
The #define directive is used to define a symbol to the preprocessor and assign
it a value. The symbol is meaningful to the preprocessor only in lines of code
following the definition.
For example, if the directive
#define NULL 0,
is included in the program, then in all lines following the definition, the symbol NULL
is replaced by the symbol 0. If the symbol NULL is encountered before the definition,
it is not replaced.
The #define directive is followed by one or more spaces or tabs and the symbol
to be defined. It cannot be a C keyword or an identifier, if it is, a syntax error is
detected by the compiler.
For example, suppose the program contains the directive
#define dumb 54
which in turn is followed by the declaration
int dumb;
This would be translated by the preprocessor into
int 54;
which would be rejected by the compiler.
If a #define directive does not fit on a single line, it can be continued on
subsequent lines. All lines of the directive except the last line must end with a
backslash() character. A directive can be split only at a point where a space is
legal.For example:
#define max(a,b) 
({ typeof (a) _a = (a); 
typeof (b) _b = (b); 
_a > _b ? _a : _b; })
Constants
A common use for defined symbols is the implementation of named constants.
The following are the examples of constants in C:
 25
 1.23
 „a‟
 “hello”
 -6
Any of these values can be assigned to a defined preprocessor symbol:
#define INTEGER 25
#define CHARACTER „a‟
A defined symbol can specify only a complete constant. For example, if a
program contains the definitions
#define NULL 0
the number 120 cannot be represented as 12NULL. A defined symbol can be
recognized only if it is delimited by a white space, punctuation, or operators.
(This rule also applies to C identifiers, such as variables or function names.)
Macros
The following is a valid preprocessor directive.
#define TEST if (a > b)
The symbol TEST is defined to be the entire contents of the directive following
the symbol TEST; that is the string
if (a > b)
The statement
TEST printf(“It workedn”);
would be translated to
if (a > b) printf(“It workedn”);
Some programmers include the following definitions in all their programs:
#define and &&
#define or ||
These definitions enable the programmer to write more readable code, such as
the following:
if(a < b or c > d and e < f)
Macros With Arguments
The C preprocessor permits macros with arguments, just as functions do.
Consider the following example:
#define Decrement(x) if(x > 0) x -= 1
( Just like a function to return the decremented valu. Note: No values returned here)
Code 1:
#include<stdio.h>
#define Decrement(x) if(x>0) x-=1
int main(void)
{
int k=11;
Decrement(k);
char c='B';
Decrement(c);
printf("%X %c",k,c);
return 1;
}
Output:
A A
Code 2:
#include<stdio.h>
#define NUM_PRINT(value,spec)printf(“value= %specn”,value)
int main(void)
{
int k=11;
NUM_PRINT(k,d);
return 1;
}
Output:
value=11
What if we have:
#define NUM_PRINT(n,spec)printf(“n= %specn”,n)
Code 3:
#include<stdio.h>
#define TOHUNDRED(x) (x * 100)
void main()
{
int a=12,b=4;
printf(“%d”,TOHUNDRED(a+b));
}
Output:
412
Code 4:
#include<stdio.h>
#define sqr(a) ((a)*(a))
int main()
{
int x=7;
printf(“%c”,(char)sqr(x));
return 1;
}
Output:
1
A macro can be defined in terms of another macro, as in the following example
of nested macros:
#define CONTROL “%dn”
#define printint(x) printf(CONTROL,x)
#define TEST(x) if(x>0) printint(x)
If the program contains the statement
TEST(w);
where w is an integer variable, the statement goes through the following conversion
types:
 if (w>0) printint(w);
 if (w>0) printf(CONTROL,w);
 if (w>0) printf(“%dn”,w);
Note:
 A macro definition cannot contain itself, as in
#define infinity infinity
#define A B
#define B A
There are also serious limits to the preprocessor‟s ability to detect hidden recursion,
so these errors might not be detected until the preprocessor attempts to make the
substitutions and finds itself in an infinite loop.
When macros and when functions?
 A function that would consist of only one line of code usually should be
implemented as a macro, to save computing time.
 If memory space is the primary consideration, however, a macro may not be
the best choice.
 Macros are more powerful than functions in that their arguments can be any
strings at all – They can be used with arguments of different types.
The #include Directive
Often a programmer accumulates a collection of useful constants and macro
definitions that are used in almost every program. It is desirable to be able to store
these definitions in a file that can be inserted automatically into every program. This
task is done by the #include directive.
A file is inserted at any point where the #include directive is encountered.
Such files are called as header files, and by convention their names end with
characters „.h‟ (as in stdio.h).
Header files can contain any text at all. Aside from preprocessor directives to
define macros, they may also contain C code to define structure templates, global
variables, or function definitions.
An example of an inclusion you have already seen is
#include<stdio.h>
in which stdio.h is the file to be included. The angular brackets tell the preprocessor
to search for the file in one or more standard directories. These directories contain
the header files that are provided by the system. If the brackets are replaced with
double quotation marks, as in
#include “stdio.h”
the preprocessor looks first in the programmer‟s own directory, or the same one that
contains the program files. If it is not found there, then standard directories are
searched.
Another common use of the header files is to provide consistency among
several program files. Often a program is so large that it is convenient to break it
down into smaller units, each of which is stored in a separate file. After these
separate program files are compiled, they must somehow be linked together to form a
single file. This linking is usually accomplished by a program called the linkage editor,
which is often run automatically when the program is compiled.
A header file can contain other #include directives. It cannot include itself,
because this would lead to infinite recursion. It cannot include another file that
includes this file, as this would also lead to infinite recursion.
C standard library
 <assert.h>
 <complex.h>
 <ctype.h>
 <errno.h>
 <fenv.h>
 <float.h>
 <inttypes.h>
 <iso646.h>
 <limits.h>
 <locale.h>
 <math.h>
 <setjmp.h>
 <signal.h>
 <stdarg.h>
 <stdbool.h>
 <stddef.h>
 <stdint.h>
 <stdio.h>
 <stdlib.h>
 <string.h>
 <tgmath.h>
 <time.h>
 <wchar.h>
 <wctype.h>
The #undef Directive
It may be necessary to redefine a macro at some point in a program. For
example, the user may wish to redefine a macro or constant specified in a header file
such as stdio.h. If only a few macros from such a file need to be redefined, the
easiest way is to use #include the entire file and then redefine the macros in the
question.
For example, suppose the programmer wishes the constant EOF to have the
value -2, the programmer could begin with the following directives:
#include<stdio.h>
#undef EOF
#define EOF -2
(In practice, it would be dangerous to redefine the value of EOF; it is done
here merely as an example)
If a preprocessor symbol has already been defined, it must be undefined before
being redefined. This is accomplished by the #undef directive, which specifies the
name of the symbol to be undefined.
It is not necessary to perform the redefinition at the beginning of a program. A
symbol can be redefined in the middle of a program, so that it has one value in the
first half and another value at the end.
A symbol need not be redefined after it is undefined. If the program uses the
symbol in a statement after the point at which it is undefined, however, the symbol is
not replaced. A defined symbol will be replaced before the point (if any) at which it is
undefined.
Conditional Compilation : #ifdef, #ifndef, #endif
The general idea behind conditional compilation is that a piece of code can be
selectively compiled, depending upon whether a specific value has been #defined, or
not. Reasons for doing this vary, but the main ones seem to be:
 Platform specific constraints
 Debug builds
 Performance issues
(When we talk of 'platform specific' here, we mean flavors of the same platform,
rather than different operating systems or hardware platforms.)
In essence, the aim is to create a different executable file (application),
depending on several flags that are set by the programmer. Although, as we shall see,
the technique is also used to prevent multiple #includes, which generate errors during
the compile process.
If an #ifdef return a true value, all the lines between the #ifdef and the
corresponding #endif directive are left in the program. If those lines contain
preprocessor directives, the directives are processed. If #ifdef evaluates as false, the
associated lines are ignored, including the preprocessor directives included.
Even though we talk about conditional compilation directives in the same terms
as the C if statement, the preprocessor directives are executed before the
compilation is initiated. Thus, there can be no overlap between the C code and the
preprocessor directives. For example, the #ifdef directive cannot be used to test for
the declaration of a variable.
The simplest sort of conditional is
#ifdef NAME
/* compile these lines if NAME is defined */
#endif
#ifndef NAME
/* compile these lines if NAME is not defined */
#endif
Sample piece of Code 1:
#ifdef LINKED_LIST
Add_node(p,&inv_list);
#endif
Sample piece of Code 2:
#ifndef MAX_LEN
#define MEX_LEN 1000
#endif
If the programmer wants FLAG never to be defined, then the following can be done:
#ifdef FLAG
#undef FLAG
#endif
Conditional Compilation : #if, #elif, #else
There are 2 main disadvantages with the #ifdef and the #ifndef directives:
 It is not possible to test whether a symbol has a specific value.
 There are no connecting logical AND or OR operators.
These are overcome by the more general #if - #else directive
#ifdef name
/*program text*/
#else
/*more program text*/
#endif
Note: #elif is available only with the ANSI C preprocessor.
#if A>47 // compiled if A is greater than 47
#else
#if A < 20 // compiled if A is less than 20
#else // compiled if A is greater than or equal
// to 20 and less than or equal to 47
#endif // end of if, A is less than 20
#endif // end of if, A is greater than 47
Any undefined preprocessor symbol used in the #if expression is treated as if it
has the value 0.
Predefined Macros:
Macro Description
__DATE__ The compilation date of the current source file. The date is a string
literal of the form Mmm dd yyyy. The month name Mmm is the same as
for dates generated by the library function asctime declared in TIME.H.
__FILE__ The name of the current source file. __FILE__ expands to a string
surrounded by double quotation marks. To ensure that the full path to
the file is displayed, use /FC (Full Path of Source Code File in
Diagnostics).
__LINE__ The line number in the current source file. The line number is a decimal
integer constant. It can be changed with a #line directive.
__STDC__ Indicates full conformance with the ANSI C standard. Defined as the
integer constant 1 only if the /Za compiler option is given and you are
not compiling C++ code; otherwise is undefined.
__TIME__ The most recent compilation time of the current source file. The time is
a string literal of the form hh:mm:ss.
__TIMESTAMP__ The date and time of the last modification of the current source file,
expressed as a string literal in the form Ddd Mmm Date hh:mm:ss yyyy,
where Ddd is the abbreviated day of the week and Date is an integer
from 1 to 31.
Code:
#include<stdio.h>
int main()
{
printf("File :%stLine %dn",__FILE__,__LINE__);
printf("Date: %stTime: %sn",__DATE__,__TIME__);
return 1;
}
Output:
File :C:Documents and SettingsS.SrikrishnanDesktoptest.c
Line 4
Date: Sep 10 2010 Time: 15:09:28
REFERENCES:
Leland L. Beck, “System Software – An Introduction to Systems Programming”, 3rd
Edition, Pearson Education Asia, 2006.
Henry Mullish, Herbert L. Cooper, “The Spirit of „C‟ – An Introduction to Modern
Programming”, Jaico Publishing House.


More Related Content

What's hot (20)

PPT
Graphics software
Mohd Arif
 
PPT
Virtual machine
Nikunj Dhameliya
 
PPTX
Ms word 2007
Dr. Priyamvada Saarsar
 
PPTX
Ch1-Operating System Concept
Muhammad Bilal Tariq
 
PDF
Word exercises (1)
ruelcdogma
 
PPTX
Application softwares
vivek shah
 
PPTX
Security services and mechanisms
Rajapriya82
 
PDF
Macro-processor
Temesgen Molla
 
PPTX
Loaders ( system programming )
Adarsh Patel
 
PPTX
Features of Control Panel
SajidHasnain3
 
PPTX
Small Basic - Branching and Loop
Grayzon Gonzales, LPT
 
PPTX
UNIT-IV
VarthiniRamesh
 
PPTX
Single Pass Assembler
Satyamevjayte Haxor
 
PPTX
Character attributes
shalinikarunakaran1
 
PPTX
Operating System Operations ppt.pptx
MSivani
 
PPTX
Window to Viewport Transformation in Computer Graphics with.pptx
Dolchandra
 
PPTX
Pagemaker
ThamizhselviKrishnam
 
PPTX
Interfacing With High Level Programming Language
.AIR UNIVERSITY ISLAMABAD
 
PPTX
Spline representations
Nikhil krishnan
 
Graphics software
Mohd Arif
 
Virtual machine
Nikunj Dhameliya
 
Ch1-Operating System Concept
Muhammad Bilal Tariq
 
Word exercises (1)
ruelcdogma
 
Application softwares
vivek shah
 
Security services and mechanisms
Rajapriya82
 
Macro-processor
Temesgen Molla
 
Loaders ( system programming )
Adarsh Patel
 
Features of Control Panel
SajidHasnain3
 
Small Basic - Branching and Loop
Grayzon Gonzales, LPT
 
Single Pass Assembler
Satyamevjayte Haxor
 
Character attributes
shalinikarunakaran1
 
Operating System Operations ppt.pptx
MSivani
 
Window to Viewport Transformation in Computer Graphics with.pptx
Dolchandra
 
Interfacing With High Level Programming Language
.AIR UNIVERSITY ISLAMABAD
 
Spline representations
Nikhil krishnan
 

Viewers also liked (18)

PDF
TASM PROFILE
Adebola Fagbowore
 
PPTX
It322 intro 4
J Cza Àkera
 
PPTX
Unit ii-111206004636-phpapp01
riddhi viradiya
 
PPTX
Microassembler a10
Sanjay Kumar Chakravarti
 
PPTX
Elena Macro Processor
Arun C S
 
PPTX
Assembly final 2
JAMIL AHMED SHAH
 
PPT
ELENA MICROPROCESSOR
ranjeetdon
 
PPT
Macro
Google
 
PPT
Lec 01 basic concepts
Abdul Khan
 
PDF
Introduction to systems programming
Mukesh Tekwani
 
PPTX
System Programming Unit III
Manoj Patil
 
PPTX
System Programming Unit II
Manoj Patil
 
PPTX
System Programing Unit 1
Manoj Patil
 
DOCX
MASM -UNIT-III
Dr.YNM
 
PPT
micro & macro economics
gilda_girish
 
PPTX
System Programming Overview
Dattatray Gandhmal
 
PPT
Italian and German Unification
Paqui Sánchez
 
PDF
Deep C
Olve Maudal
 
TASM PROFILE
Adebola Fagbowore
 
It322 intro 4
J Cza Àkera
 
Unit ii-111206004636-phpapp01
riddhi viradiya
 
Microassembler a10
Sanjay Kumar Chakravarti
 
Elena Macro Processor
Arun C S
 
Assembly final 2
JAMIL AHMED SHAH
 
ELENA MICROPROCESSOR
ranjeetdon
 
Macro
Google
 
Lec 01 basic concepts
Abdul Khan
 
Introduction to systems programming
Mukesh Tekwani
 
System Programming Unit III
Manoj Patil
 
System Programming Unit II
Manoj Patil
 
System Programing Unit 1
Manoj Patil
 
MASM -UNIT-III
Dr.YNM
 
micro & macro economics
gilda_girish
 
System Programming Overview
Dattatray Gandhmal
 
Italian and German Unification
Paqui Sánchez
 
Deep C
Olve Maudal
 
Ad

Similar to ANSI C Macros (20)

PPTX
Preprocessor
lalithambiga kamaraj
 
DOCX
Basic structure of c programming
TejaswiB4
 
DOCX
Basic structure of c programming
TejaswiB4
 
PDF
6 preprocessor macro header
hasan Mohammad
 
PPTX
Programming Fundamentals lecture 5
REHAN IJAZ
 
PDF
Chapter 13.1.11
patcha535
 
PPT
Preprocessors
Koganti Ravikumar
 
PPTX
Functions and Header files ver very useful
RamSiddesh1
 
PPTX
STRUCTURED PROGRAMMING (USING C PROGRAMMING).pptx
stevecom2010
 
PDF
2. Consider the following C program #define M ... #define N ....pdf
SIGMATAX1
 
PPT
Preprocessors
Gourav Arora
 
PPTX
5.Hello World program Explanation. ||C Programming tutorial.
Fiaz Hussain
 
PPTX
Sample for Simple C Program - R.D.Sivakumar
Sivakumar R D .
 
PPTX
Basics of c Nisarg Patel
TechNGyan
 
PPTX
UNIT 4A-preprocessor.pptx for c language and basic knowledge
2024163103shubham
 
PPTX
C programming
PralhadKhanal1
 
PDF
05 -working_with_the_preproce
Hector Garzo
 
PPTX
C++ AND CATEGORIES OF SOFTWARE
UNIVERSITY OF ENGINEERING AND TECHNOLOGY TAXILA
 
PPT
Chapter3
Kamran
 
Preprocessor
lalithambiga kamaraj
 
Basic structure of c programming
TejaswiB4
 
Basic structure of c programming
TejaswiB4
 
6 preprocessor macro header
hasan Mohammad
 
Programming Fundamentals lecture 5
REHAN IJAZ
 
Chapter 13.1.11
patcha535
 
Preprocessors
Koganti Ravikumar
 
Functions and Header files ver very useful
RamSiddesh1
 
STRUCTURED PROGRAMMING (USING C PROGRAMMING).pptx
stevecom2010
 
2. Consider the following C program #define M ... #define N ....pdf
SIGMATAX1
 
Preprocessors
Gourav Arora
 
5.Hello World program Explanation. ||C Programming tutorial.
Fiaz Hussain
 
Sample for Simple C Program - R.D.Sivakumar
Sivakumar R D .
 
Basics of c Nisarg Patel
TechNGyan
 
UNIT 4A-preprocessor.pptx for c language and basic knowledge
2024163103shubham
 
C programming
PralhadKhanal1
 
05 -working_with_the_preproce
Hector Garzo
 
C++ AND CATEGORIES OF SOFTWARE
UNIVERSITY OF ENGINEERING AND TECHNOLOGY TAXILA
 
Chapter3
Kamran
 
Ad

More from Srikrishnan Suresh (10)

PPTX
Sources of Innovation
Srikrishnan Suresh
 
PDF
Second review presentation
Srikrishnan Suresh
 
PDF
First review presentation
Srikrishnan Suresh
 
PDF
Final presentation
Srikrishnan Suresh
 
PDF
Zeroth review presentation
Srikrishnan Suresh
 
PDF
All pairs shortest path algorithm
Srikrishnan Suresh
 
PDF
Canvas based presentation
Srikrishnan Suresh
 
PDF
Merge sort
Srikrishnan Suresh
 
PDF
Theory of LaTeX
Srikrishnan Suresh
 
PDF
Design Patterns
Srikrishnan Suresh
 
Sources of Innovation
Srikrishnan Suresh
 
Second review presentation
Srikrishnan Suresh
 
First review presentation
Srikrishnan Suresh
 
Final presentation
Srikrishnan Suresh
 
Zeroth review presentation
Srikrishnan Suresh
 
All pairs shortest path algorithm
Srikrishnan Suresh
 
Canvas based presentation
Srikrishnan Suresh
 
Merge sort
Srikrishnan Suresh
 
Theory of LaTeX
Srikrishnan Suresh
 
Design Patterns
Srikrishnan Suresh
 

Recently uploaded (20)

PDF
TrustArc Webinar - Data Privacy Trends 2025: Mid-Year Insights & Program Stra...
TrustArc
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PPTX
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
PDF
Complete Network Protection with Real-Time Security
L4RGINDIA
 
PDF
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PDF
Blockchain Transactions Explained For Everyone
CIFDAQ
 
PDF
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
PDF
Building Resilience with Digital Twins : Lessons from Korea
SANGHEE SHIN
 
PDF
Persuasive AI: risks and opportunities in the age of digital debate
Speck&Tech
 
PPTX
Building a Production-Ready Barts Health Secure Data Environment Tooling, Acc...
Barts Health
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PPTX
MSP360 Backup Scheduling and Retention Best Practices.pptx
MSP360
 
PDF
The Builder’s Playbook - 2025 State of AI Report.pdf
jeroen339954
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
TrustArc Webinar - Data Privacy Trends 2025: Mid-Year Insights & Program Stra...
TrustArc
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
Complete Network Protection with Real-Time Security
L4RGINDIA
 
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
Blockchain Transactions Explained For Everyone
CIFDAQ
 
DevBcn - Building 10x Organizations Using Modern Productivity Metrics
Justin Reock
 
Building Resilience with Digital Twins : Lessons from Korea
SANGHEE SHIN
 
Persuasive AI: risks and opportunities in the age of digital debate
Speck&Tech
 
Building a Production-Ready Barts Health Secure Data Environment Tooling, Acc...
Barts Health
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
MSP360 Backup Scheduling and Retention Best Practices.pptx
MSP360
 
The Builder’s Playbook - 2025 State of AI Report.pdf
jeroen339954
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 

ANSI C Macros

  • 1. ANSI C Macros – The C Preprocessor S.SRIKRISHNAN PRE - FINAL YEAR SSN COLLEGE OF ENGINEERING ne of the features not included in the original C language was the concept of constants. In order to accommodate various features, (including constants), the authors of C developed the C preprocessor. None of the services provided by the C preprocessor (cpp) is indispensible for writing C programs, but these services make the task considerably easier. Outline: 1. How the preprocessor works 2. The #define Directive 3. Constants 4. Macros 5. Macros with Arguments 6. The #undef Directive 7. The #include Directive 8. Conditional compilation : #ifdef, #ifndef, #endif 9. Conditional compilation : #if, #else 10.Predefined Macros O
  • 2. How The Preprocessor Works  When you issue the command to compile a C program, the program is run automatically through the preprocessor  The preprocessor is a program that modifies the C source program according to the directives supplied in the program.  The preprocessor does not modify the program file, but creates a new file that contains the processed version of the program.  This new file is then submitted to the compiler. Fig(a) The Compilation Process If a program contains the directive #define NULL 0, and the statement x = NULL; the preprocessor replaces every occurrence of NULL following the #define directive with 0. The resulting program no longer includes the directive (since the directives are only for the preprocessor, not the compiler), and the preceding statement now reads as follows: x = 0; Constants, therefore, are abbreviations supplied for the convenience of the programmer. Each occurrence of a constant is translated by the preprocessor so that
  • 3. the program is comprehensible to the C compiler. The preprocessor can also delete or add C program statements. Note:  All preprocessor directives begin with the number or sharp sign (#).  The directive is terminated not by a semicolon, but by the end of the line on which it appears.  Only one directive can occur on a line.  A preprocessor symbol is never replaced if it occurs within single or double quotation marks.  The preprocessor does not check for normal C syntax, except for identifying quotation marks. It merely substitutes symbols where it finds them. The #define Directive The #define directive is used to define a symbol to the preprocessor and assign it a value. The symbol is meaningful to the preprocessor only in lines of code following the definition. For example, if the directive #define NULL 0, is included in the program, then in all lines following the definition, the symbol NULL is replaced by the symbol 0. If the symbol NULL is encountered before the definition, it is not replaced. The #define directive is followed by one or more spaces or tabs and the symbol to be defined. It cannot be a C keyword or an identifier, if it is, a syntax error is detected by the compiler. For example, suppose the program contains the directive #define dumb 54 which in turn is followed by the declaration
  • 4. int dumb; This would be translated by the preprocessor into int 54; which would be rejected by the compiler. If a #define directive does not fit on a single line, it can be continued on subsequent lines. All lines of the directive except the last line must end with a backslash() character. A directive can be split only at a point where a space is legal.For example: #define max(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); _a > _b ? _a : _b; }) Constants A common use for defined symbols is the implementation of named constants. The following are the examples of constants in C:  25  1.23  „a‟  “hello”  -6 Any of these values can be assigned to a defined preprocessor symbol: #define INTEGER 25 #define CHARACTER „a‟ A defined symbol can specify only a complete constant. For example, if a program contains the definitions #define NULL 0 the number 120 cannot be represented as 12NULL. A defined symbol can be recognized only if it is delimited by a white space, punctuation, or operators. (This rule also applies to C identifiers, such as variables or function names.)
  • 5. Macros The following is a valid preprocessor directive. #define TEST if (a > b) The symbol TEST is defined to be the entire contents of the directive following the symbol TEST; that is the string if (a > b) The statement TEST printf(“It workedn”); would be translated to if (a > b) printf(“It workedn”); Some programmers include the following definitions in all their programs: #define and && #define or || These definitions enable the programmer to write more readable code, such as the following: if(a < b or c > d and e < f) Macros With Arguments The C preprocessor permits macros with arguments, just as functions do. Consider the following example: #define Decrement(x) if(x > 0) x -= 1 ( Just like a function to return the decremented valu. Note: No values returned here)
  • 6. Code 1: #include<stdio.h> #define Decrement(x) if(x>0) x-=1 int main(void) { int k=11; Decrement(k); char c='B'; Decrement(c); printf("%X %c",k,c); return 1; } Output: A A Code 2: #include<stdio.h> #define NUM_PRINT(value,spec)printf(“value= %specn”,value) int main(void) { int k=11; NUM_PRINT(k,d); return 1; } Output: value=11 What if we have: #define NUM_PRINT(n,spec)printf(“n= %specn”,n) Code 3: #include<stdio.h> #define TOHUNDRED(x) (x * 100) void main() { int a=12,b=4; printf(“%d”,TOHUNDRED(a+b)); }
  • 7. Output: 412 Code 4: #include<stdio.h> #define sqr(a) ((a)*(a)) int main() { int x=7; printf(“%c”,(char)sqr(x)); return 1; } Output: 1 A macro can be defined in terms of another macro, as in the following example of nested macros: #define CONTROL “%dn” #define printint(x) printf(CONTROL,x) #define TEST(x) if(x>0) printint(x) If the program contains the statement TEST(w); where w is an integer variable, the statement goes through the following conversion types:  if (w>0) printint(w);  if (w>0) printf(CONTROL,w);  if (w>0) printf(“%dn”,w); Note:  A macro definition cannot contain itself, as in #define infinity infinity #define A B
  • 8. #define B A There are also serious limits to the preprocessor‟s ability to detect hidden recursion, so these errors might not be detected until the preprocessor attempts to make the substitutions and finds itself in an infinite loop. When macros and when functions?  A function that would consist of only one line of code usually should be implemented as a macro, to save computing time.  If memory space is the primary consideration, however, a macro may not be the best choice.  Macros are more powerful than functions in that their arguments can be any strings at all – They can be used with arguments of different types. The #include Directive Often a programmer accumulates a collection of useful constants and macro definitions that are used in almost every program. It is desirable to be able to store these definitions in a file that can be inserted automatically into every program. This task is done by the #include directive. A file is inserted at any point where the #include directive is encountered. Such files are called as header files, and by convention their names end with characters „.h‟ (as in stdio.h). Header files can contain any text at all. Aside from preprocessor directives to define macros, they may also contain C code to define structure templates, global variables, or function definitions. An example of an inclusion you have already seen is #include<stdio.h> in which stdio.h is the file to be included. The angular brackets tell the preprocessor to search for the file in one or more standard directories. These directories contain
  • 9. the header files that are provided by the system. If the brackets are replaced with double quotation marks, as in #include “stdio.h” the preprocessor looks first in the programmer‟s own directory, or the same one that contains the program files. If it is not found there, then standard directories are searched. Another common use of the header files is to provide consistency among several program files. Often a program is so large that it is convenient to break it down into smaller units, each of which is stored in a separate file. After these separate program files are compiled, they must somehow be linked together to form a single file. This linking is usually accomplished by a program called the linkage editor, which is often run automatically when the program is compiled. A header file can contain other #include directives. It cannot include itself, because this would lead to infinite recursion. It cannot include another file that includes this file, as this would also lead to infinite recursion. C standard library  <assert.h>  <complex.h>  <ctype.h>  <errno.h>  <fenv.h>  <float.h>  <inttypes.h>  <iso646.h>  <limits.h>  <locale.h>  <math.h>  <setjmp.h>  <signal.h>
  • 10.  <stdarg.h>  <stdbool.h>  <stddef.h>  <stdint.h>  <stdio.h>  <stdlib.h>  <string.h>  <tgmath.h>  <time.h>  <wchar.h>  <wctype.h> The #undef Directive It may be necessary to redefine a macro at some point in a program. For example, the user may wish to redefine a macro or constant specified in a header file such as stdio.h. If only a few macros from such a file need to be redefined, the easiest way is to use #include the entire file and then redefine the macros in the question. For example, suppose the programmer wishes the constant EOF to have the value -2, the programmer could begin with the following directives: #include<stdio.h> #undef EOF #define EOF -2 (In practice, it would be dangerous to redefine the value of EOF; it is done here merely as an example) If a preprocessor symbol has already been defined, it must be undefined before being redefined. This is accomplished by the #undef directive, which specifies the name of the symbol to be undefined.
  • 11. It is not necessary to perform the redefinition at the beginning of a program. A symbol can be redefined in the middle of a program, so that it has one value in the first half and another value at the end. A symbol need not be redefined after it is undefined. If the program uses the symbol in a statement after the point at which it is undefined, however, the symbol is not replaced. A defined symbol will be replaced before the point (if any) at which it is undefined. Conditional Compilation : #ifdef, #ifndef, #endif The general idea behind conditional compilation is that a piece of code can be selectively compiled, depending upon whether a specific value has been #defined, or not. Reasons for doing this vary, but the main ones seem to be:  Platform specific constraints  Debug builds  Performance issues (When we talk of 'platform specific' here, we mean flavors of the same platform, rather than different operating systems or hardware platforms.) In essence, the aim is to create a different executable file (application), depending on several flags that are set by the programmer. Although, as we shall see, the technique is also used to prevent multiple #includes, which generate errors during the compile process. If an #ifdef return a true value, all the lines between the #ifdef and the corresponding #endif directive are left in the program. If those lines contain preprocessor directives, the directives are processed. If #ifdef evaluates as false, the associated lines are ignored, including the preprocessor directives included. Even though we talk about conditional compilation directives in the same terms as the C if statement, the preprocessor directives are executed before the compilation is initiated. Thus, there can be no overlap between the C code and the preprocessor directives. For example, the #ifdef directive cannot be used to test for the declaration of a variable.
  • 12. The simplest sort of conditional is #ifdef NAME /* compile these lines if NAME is defined */ #endif #ifndef NAME /* compile these lines if NAME is not defined */ #endif Sample piece of Code 1: #ifdef LINKED_LIST Add_node(p,&inv_list); #endif Sample piece of Code 2: #ifndef MAX_LEN #define MEX_LEN 1000 #endif If the programmer wants FLAG never to be defined, then the following can be done: #ifdef FLAG #undef FLAG #endif Conditional Compilation : #if, #elif, #else There are 2 main disadvantages with the #ifdef and the #ifndef directives:  It is not possible to test whether a symbol has a specific value.  There are no connecting logical AND or OR operators. These are overcome by the more general #if - #else directive #ifdef name /*program text*/ #else /*more program text*/ #endif
  • 13. Note: #elif is available only with the ANSI C preprocessor. #if A>47 // compiled if A is greater than 47 #else #if A < 20 // compiled if A is less than 20 #else // compiled if A is greater than or equal // to 20 and less than or equal to 47 #endif // end of if, A is less than 20 #endif // end of if, A is greater than 47 Any undefined preprocessor symbol used in the #if expression is treated as if it has the value 0. Predefined Macros: Macro Description __DATE__ The compilation date of the current source file. The date is a string literal of the form Mmm dd yyyy. The month name Mmm is the same as for dates generated by the library function asctime declared in TIME.H. __FILE__ The name of the current source file. __FILE__ expands to a string surrounded by double quotation marks. To ensure that the full path to the file is displayed, use /FC (Full Path of Source Code File in Diagnostics). __LINE__ The line number in the current source file. The line number is a decimal integer constant. It can be changed with a #line directive. __STDC__ Indicates full conformance with the ANSI C standard. Defined as the integer constant 1 only if the /Za compiler option is given and you are not compiling C++ code; otherwise is undefined. __TIME__ The most recent compilation time of the current source file. The time is a string literal of the form hh:mm:ss. __TIMESTAMP__ The date and time of the last modification of the current source file, expressed as a string literal in the form Ddd Mmm Date hh:mm:ss yyyy, where Ddd is the abbreviated day of the week and Date is an integer from 1 to 31. Code: #include<stdio.h> int main() { printf("File :%stLine %dn",__FILE__,__LINE__);
  • 14. printf("Date: %stTime: %sn",__DATE__,__TIME__); return 1; } Output: File :C:Documents and SettingsS.SrikrishnanDesktoptest.c Line 4 Date: Sep 10 2010 Time: 15:09:28 REFERENCES: Leland L. Beck, “System Software – An Introduction to Systems Programming”, 3rd Edition, Pearson Education Asia, 2006. Henry Mullish, Herbert L. Cooper, “The Spirit of „C‟ – An Introduction to Modern Programming”, Jaico Publishing House. 