![Page 1: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/1.jpg)
1
• Preprocessor– How it works
• File Inclusion: #include
• Macro Definition: #define
• Predefined macros– __LINE__, __FILE__, __DATE__, __TIME__
• Conditional Compilation– #if-#endif– #if-#elif-#else-#endif– #ifdef-#endif– #ifndef-#endif– #error
Today’s Material
![Page 2: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/2.jpg)
2
• Commands that begin with # character are called preprocessor directives– Recall #include, #define
• The following diagram shows the preprocessor’s role in the compilation process
Preprocessor
prog.i
COMPILER
prog.c
PREPROCESSOR (cpp)
Modified C program [text file]
Source code [text file]
prog.o Object Code [binary file]
![Page 3: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/3.jpg)
3
• Input to the preprocessor is a C program containing directives– Preprocessor executes these directives
(commands) and removes them (including comments)
• The output of the preprocessor is an edited version of the C program containing no preprocessor directives– The output of the preprocessor directly goes into
the compiler, which generates the C object code– In fact, the compiler first generates an assembly
code, which is fed into an assembler, which generates the object code
Preprocessor: How it works
![Page 4: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/4.jpg)
4
• Preprocessor directives fall in the following categories
1. File inclusion– #include
2. Macro Definition– #define
3. Conditional Compilation– #if, #ifdef, #ifndef, #elif, #else, #endif
4. Rest of the Directives– #error, #line, #pragma– Specialized and less often used
Preprocessor Directives
![Page 5: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/5.jpg)
5
• Directives always start with # char– # char need not be at the beginning of a line, as
long as only white space precedes it– #include …– #include …
• Any number of spaces and horizontal tab chars may separate the tokens in a directive– #include …– # include …– #include …– # include …
Preprocessor Directive Format(1)
![Page 6: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/6.jpg)
6
• Directives always ends at the first new-line char unless explicitly continued
Preprocessor Directive Format(2)
#define A 2*3 /* ends at the end of the line */
#define B 2* \ /* continues at the next line */3* \ /* continues at the next line */
4 /* ends at the end of the line */
/* Same as #define B 2*3*4 *//* Backslash (\) is the continuation character */
![Page 7: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/7.jpg)
7
• Tells the preprocessor to open a particular file, and “include” its contents as part of the file being processed
#include Directive(1)
#include <stdio.h>main(){ printf(“Hello World\n”);}
• Instructs the preprocessor to open file named stdio.h (located in /usr/include/stdio.h), and bring its contents into the program
% cpp –o hello.i hello.c/* To see what’s included from stdio.h */
![Page 8: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/8.jpg)
8
#include Directive(2)#include <defs.h>/* Search defs.h in standard include directories * i.e., /usr/include, and in any other directory * specified by –I compiler flag * Example: */
% gcc –I/root den.c/* -I/root means that in addition to searching * /usr/include, we want the compiler to also search * /root for any files included with <>, */
#include “defs.h”/* means: Search defs.h in standard include * directories (/usr/include) AND the current * directory */
![Page 9: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/9.jpg)
9
• #define directive defines a macro– a name that represents something else, typically
a constant of some kind
• When the macro is used in the program, the preprocessor expands the macro, replacing it with its definition– This replacement is literal or verbatim
#define Directive(1)
#define N 100int A[N];/* becomes * int A[100]; * after preprocessor processes the C program */
![Page 10: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/10.jpg)
10
#define Example/* Some comment */#define FREEZING_POINT 32#define SCALING_FACTOR 1.8
main(){ float fahrenheit, celsius;
fahrenheit = 75; celsius = (fahrenheit-FREEZING_POINT)/SCALING_FACTOR;}
blankblankblank
main(){ float fahrenheit, celsius;
fahrenheit = 75; celsius = (fahrenheit-32)/1.8;}
Macros Expanded
Comment removed
Macro definitions removed
![Page 11: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/11.jpg)
11
• Macros are expanded literally
#define: Caveats
#define N =100int A[N]; expanded to int A[=100];
#define N 100;int A[N]; expanded to int A[100;];
![Page 12: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/12.jpg)
12
• Simple macros are primarily used to define constants
#define: Primary Usage
#define TRUE 1#define FALSE 0#define PI 3.14159#define DEBUG /* It is OK for the replacement list to be empty */
![Page 13: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/13.jpg)
13
#define: Advantages
• Using #define to create names for constants has several significant advantages– Makes programs easier to read– Makes programs easier to modify– Helps avoid inconsistencies and typos:
• It is difficult to consistently type 3.14159
![Page 14: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/14.jpg)
14
Parameterized Macros
• There must be NO space between macro name and the left parenthesis– If there is a space, the preprocessor assumes
that (..) is part of the replacement list
• x1, x2, x3, …, xn are identifiers – Called the macro’s parameters– Parameters may appear as many times as
desired in the replacement list
#define identifier(x1,x2,x3,..,xn) replacement-list
![Page 15: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/15.jpg)
15
Macro Example#define MAX(x,y) x>y?x:y#define MULT(x,y) x*y
main(){ int i, a=2, b=3; i = MAX(a,b); /* Expanded to i = a>b?a:b; */ i = MULT(a,b); /* Expanded to i = a*b; */ i = MULT(a+2, b+3); /* Expanded to i = a+2*b+3; */ /* This last MULT will produce incorrect result * To fix the problem, you need to parenthesize * the macro as follows: */} /* end-main */
#define MULT(a,b) ((a)*(b))i = MULT(a+2, b+3); /* Expanded to */i = ((a+2)*(b+3)); /* Correct now */
![Page 16: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/16.jpg)
16
• A macro definition can extend to several lines– Must continue the lines by ‘\’ char
Macros (More)
#define SAMPLE(x,y,z,t) (\ (x)+\ (y)+\ (z)+\ (t)\ )
• A macro definition can make use of other macros defined earlier
#define MAX(a,b) ((a)>(b)?(a):(b))#define MAX3(x,y,z) (MAX(x, MAX(y,z)))
![Page 17: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/17.jpg)
17
• A parameterized macro can have an empty parameter list
Macros (More)
#define getchar() fgetc(stdin)
/* This is how getchar is defined in <stdio.h> * () is really not needed, but makes getchar * look like a function. So it is used. */
![Page 18: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/18.jpg)
18
Macros: Important Note
• A parameterized macro is NOT a function
• When the preprocessor encounters a macro, it simply expands it within the source code
• Thus the compiler is NOT even aware that the code has been generated by a macro expansion
![Page 19: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/19.jpg)
19
Advantages of Macros over Functions
1. Program is slightly faster– No overhead of a function call and function
return
2. Macro parameters are generic– Macro parameters do not have types– So we can use the same macro with int, float,
double etc. arguments. E.g., MAX macro defined earlier
![Page 20: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/20.jpg)
20
Disadvantages of Macros over Functions
1. Compiled code will be larger• Since macros are expanded within the source
code, the size of the code gets big
2. Arguments are not type-checked• With functions, the compiler type-checks the
arguments and warns you if there is an error• With macros, this type-checking is NOT possible
3. Macros may evaluate their arguments more than once
n = MAX(i++, j); /* Expanded to */n = (i++ > j)?(i++):(j);/* If i is greater than j, i will be incremented twice, * and n gets the wrong value *//* If MAX was a function, n would get the bigger of i &j and * i would be incremented once. This is due to the fact that * function arguments are evaluated before the function call */
![Page 21: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/21.jpg)
21
Macro Scope
• Macro definitions remain in effect until the end of the file in which they appear
• Macros may be undefined by #undef directive– #undef identifier– #undef is typically used to remove the existing
definition of a macro, so that it can be redefined
![Page 22: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/22.jpg)
22
Predefined Macros(1)• Predefined macros
__LINE__ : Line # of the file being compiled__FILE__ : Name of the file being compiled__DATE__ : Date of compilation “Mmm dd yyyy”__TIME__ : Time of compilation “hh:mm:ss”
printf(This software is compiled on %s at %s\n”, __DATE__, _TIME__);
![Page 23: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/23.jpg)
23
Predefined Macros(2)• We can use _LINE__ and _FILE__ macros to
locate errors#define CHECK_ZERO(divisor)\ if (divisor==0) {\ printf(“**Attempt to divide by zero on line ” \ “%d of file %s**\n”, __LINE__, __FILE__); \ exit(1); /* Terminate the program */ \ } /* end-if */
• Let’s use this macro in our program
CHECK_ZERO(j);k = i/j;
/* if j is zero, CHECK_ZERO will print an error * message and terminate the program */
![Page 24: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/24.jpg)
24
assert macro• C Library provides a similar macro named
assert– Need to include <assert.h>#include <assert.h>
int i, k;i = 0;assert(i!=0);k = 20/i;
• Assert is defined as follows
#define assert(c) \ if (c){ \ printf(“Assertion failed %s\n”, #c); \ } /* end-if */
/* #c makes c a string */
![Page 25: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/25.jpg)
25
Conditional Compilation• C preprocessor recognizes a number of
directives that support conditional compilation– The inclusion or exclusion of a section of a
program text depending on the outcome of a test performed by the preprocessor
• Conditional Compilation Directives are– #if-#endif– #if-#else-#endif– #if-#elif-#else-#endif– #ifdef-#endif– #ifndef-#endif
![Page 26: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/26.jpg)
26
#if-#endif• Suppose there is a section of code that you
want to have compiled based on a condition• Classical example is the debug code that
you insert in your programs– You want to compile your program with the
debug code to see the debug output when debugging
– When the program is all debugged & you do not want to see the debug output anymore, you simply want to avoid compiling that section of the code rather than remove it
– Here is how you can achieve it
![Page 27: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/27.jpg)
27
#if-#endif#define DEBUG 1 /* Simply set DEBUG to 0 if you don’t * want to see the debug output */#if DEBUG
printf(“i: %d\n”, i); printf(“j: %d\n”, j);#endif
• In general, #if directive has the form
#if constant-expression .. .. ..#endif
![Page 28: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/28.jpg)
28
#if-#elif-#else-#endif• #if, #endif can be nested just like ordinary if
statements using #elif, #else directives
#define DEBUG 1
#if DEBUG == 1 .. ..#else .. ..#endif
#define DEBUG 1
#if DEBUG == 1 .. ..#elif DEBUG == 2 .. ..#else .. ..#endif
![Page 29: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/29.jpg)
29
defined operator• Defined operator allows you to test whether
a macro is defined yet– You can use this operator in #if, #elif directives
#if defined(WINDOWS) int g = 3; ..#elif defined(LINUX) int g = 2; ..#elif defined(SOLARIS) int g = 4; ..#else .. ..#endif
• Example: – You want to initiate
a variable/declare a function differently depending on the OS
![Page 30: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/30.jpg)
30
#ifdef, #ifndef• Instead of using defined operator, there is a
shorter way to write the same code using #ifdef & #ifndef
#ifdef WINDOWS int g = 3; ..#endif
#ifdef LINUX int g = 2; ..#endif
#ifdef SOLARIS int g = 4; ..#endif
• Using #ifndef you want the code to get compiled when the macro is NOT defined
![Page 31: 1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation](https://reader036.vdocuments.mx/reader036/viewer/2022062722/56649f295503460f94c433f6/html5/thumbnails/31.jpg)
31
Other Directives• #error message
– When the preprocessor encounters an #error directive, it prints the error “message”
#if INT_MAX < 100000#error int type is too small!#endif
• #error directive is often found in the #else part of an #if-#elif-#endif series
#if defined(WINDOWS) ..#elif define(LINUX) ..#else#error No OS specified#endif