Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation.

Similar presentations


Presentation on theme: "1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation."— Presentation transcript:

1 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

2 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]

3 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

4 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

5 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 … Any number of spaces and horizontal tab chars may separate the tokens in a directive –#include … Preprocessor Directive Format(1)

6 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 B2* \ /* 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 */

7 7 Tells the preprocessor to open a particular file, and “include” its contents as part of the file being processed #include Directive(1) #include 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 */

8 8 #include Directive(2) #include /* 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 */

9 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 100 int A[N]; /* becomes * int A[100]; * after preprocessor processes the C program */

10 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; } blank main(){ float fahrenheit, celsius; fahrenheit = 75; celsius = (fahrenheit-32)/1.8; } Macros Expanded Comment removed Macro definitions removed

11 11 Macros are expanded literally #define: Caveats #define N =100 int A[N];  expanded to int A[=100]; #define N 100; int A[N];  expanded to int A[100;];

12 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 */

13 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

14 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

15 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 */

16 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)))

17 17 A parameterized macro can have an empty parameter list Macros (More) #define getchar() fgetc(stdin) /* This is how getchar is defined in * () is really not needed, but makes getchar * look like a function. So it is used. */

18 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

19 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

20 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 */

21 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

22 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__);

23 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 */

24 24 assert macro C Library provides a similar macro named assert –Need to include #include 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 */

25 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

26 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

27 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

28 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

29 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

30 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

31 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


Download ppt "1 Preprocessor –How it works File Inclusion: #include Macro Definition: #define Predefined macros –__LINE__, __FILE__, __DATE__, __TIME__ Conditional Compilation."

Similar presentations


Ads by Google