preprocessor statements r inkulu http iitg ac in rinkulu
play

Preprocessor Statements R. Inkulu http://www.iitg.ac.in/rinkulu/ - PowerPoint PPT Presentation

Preprocessor Statements R. Inkulu http://www.iitg.ac.in/rinkulu/ (Preprocessor Statements) 1 / 18 File inclusion abc.h : abc.c after compiler int func1(float); pre-processing: float func2(double, double); int func1(float); . . . float


  1. Preprocessor Statements R. Inkulu http://www.iitg.ac.in/rinkulu/ (Preprocessor Statements) 1 / 18

  2. File inclusion abc.h : abc.c after compiler int func1(float); pre-processing: float func2(double, double); int func1(float); . . . float func2(double, double); . . . abc.c : int func1(float) { . . . } #include ”abc.h” float func2(double, double) { int func1(float) { . . . } . . . } float func2(double, double) { . . . . . . } . . . main.c after compiler pre-processing: main.c : int func1(float); #include ”abc.h” float func2(double, double); int main(void) { . . . int k = func1(35.678); int main(void) { } int k = func1(35.678); } (Preprocessor Statements) 2 / 18

  3. Macro Substitution . . . #define ARRAYSIZE 512 . . . int func(double) { int func(double) { . . . . . . int buffer1[ARRAYSIZE]; int buffer1[512]; . . . . . . double buffer2[ARRAYSIZE]; double buffer2[512]; . . . . . . char buffer3[512]; char buffer3[ARRAYSIZE]; . . . . . . } } • Errors due to duplication can be eliminated (Preprocessor Statements) 3 / 18

  4. Macro with arguments: parenthesization issue . . . #define SQUARE(x) x*x . . . int func(void) { int func(void) { . . . . . . double f = SQUARE(23.89); double f = 23.89*23.89; . . . . . . int i = 2, j = 3; int i = 2, j = 3; int k = SQUARE(i+j); int k = i+j*i+j; . . . . . . } } • precedence issue with the second substitution (Preprocessor Statements) 4 / 18

  5. Macro with arguments: local fix . . . #define SQUARE(x) x*x . . . int func(void) { int func(void) { . . . . . . double f = double f = (23.89)*(23.89); SQUARE((23.89)); . . . . . . int i = 2, j = 3; int i = 2, j = 3; int k = (i+j)*(i+j); int k = SQUARE((i+j)); . . . . . . } } (Preprocessor Statements) 5 / 18

  6. Macro with arguments: global fix . . . #define SQUARE(x) ((x)*(x)) . . . int func(void) { int func(void) { . . . . . . double f = ((23.89)*(23.89)); double f = SQUARE(23.89); . . . . . . int i = 2, j = 3; int i = 2, j = 3; int k = ((i+j)*(i+j))/7; int k = SQUARE(i+j)/7; . . . . . . } } (Preprocessor Statements) 6 / 18

  7. Macro with arguments: unavoidable side effect . . . #define SQUARE(x) ((x)*(x)) . . . int func(void) { int func(void) { . . . . . . double f = ((23.89)*(23.89)); double f = SQUARE(23.89); . . . . . . int i = 2, j = 3; int i = 2, j = 3; int k = ((++i)*(++i)); int k = SQUARE(++i); assert (i == 3); assert (i == 3); . . . . . . } } • in the second substitution, i is incremented twice → could be an unexpected result (Preprocessor Statements) 7 / 18

  8. if statement and a macro incorrect code: semantics changed . . . #define SWAP(x, y, w) w=x; x=y; y=w; int func(void) { . . . . . . int func(void) { int i=3,j=8,t=-1; . . . if (i > j) t=i; i=j; j=t;; int i=3,j=8,t=-1; . . . if (i > j) SWAP(i, j, t); printf(”%d,%d”, i, j); . . . //prints 8, -1 ! . . . printf(”%d,%d”, i, j); } . . . } (Preprocessor Statements) 8 / 18

  9. if-else statement and a macro: poor fix incorrect code: leads to compile-time error . . . #define SWAP(x, y, w) { w=x; x=y; y=w; } . . . void func2(void) { . . . } int func(void) { int func(void) { . . . . . . int i=3,j=8,t=-1; int i=3,j=8,t=-1; if (i > j) SWAP(i, j, t); if (i > j) { t=i; i=j; j=t; } ; else func2(); else func2(); . . . . . . } } • semicolon after SWAP(i, j) is the reason for havoc (Preprocessor Statements) 9 / 18

  10. if-else statement and a macro: right fix . . . #define SWAP(x, y, w) do { w=x; x=y; y=w; } while (0) . . . void func2(void) { . . . } int func(void) { int func(void) { . . . . . . int i=3,j=8,t=-1; int i=3,j=8,t=-1; if (i > j) SWAP(i, j, t); if (i > j) do { t=i; i=j; j=t; } else func2(); while(0); . . . else func2(); } . . . } (Preprocessor Statements) 10 / 18

  11. Quoted string macro . . . int func(void) { #define DPRINT(expr) . . . printf(”debug start ” #expr int x = 8, y = 4; ”=%d”, expr) printf(”debug start ” ”x/y” . . . ”= %d”, x/y); int func(void) { . . . . . . } int x = 8, y = 4; DPRINT(x/y); . . . } int func(void) { . . . int x = 8, y = 4; printf(”debug start x/y=%d”, x/y); . . . } (Preprocessor Statements) 11 / 18

  12. Macros with arguments vs Functions adv with macros: • no func invocation cost in the runtime, hence faster • useful in making small functions inline disadv with macros: • size of object file increases • no type checking of parameters • side-effects multiple prefix/postfix operations per substitution precedence issues using macro between if-else keywords • difficult to debug while having breakpoints within a macro (Preprocessor Statements) 12 / 18

  13. Few popular macros • getchar • putchar • va start • va arg • va end • DATE date of compilation • TIME time of compilation • LINE line number • FILE name of file (Preprocessor Statements) 13 / 18

  14. Duplicate inclusion due to multiple header file inclusions abc1.h : abc4.c : typedef struct { #include ”abc2.h” . . . #include ”abc3.h” } Home; extern int globalVar; int main(void) { . . . . . . abc2.h : Home home = func2(35.67, #include ”abc1.h” 89.05); . . . . . . Home func2(double, double); func3(home); . . . . . . abc3.h : } #include ”abc1.h” . . . void func3(Home); . . . (Preprocessor Statements) 14 / 18

  15. Conditional compilation abc1.h : abc4.c : #ifndef FILEABC1 #include ”abc2.h” #define FILEABC1 #include ”abc3.h” typedef struct { . . . int main(void) { } Home; . . . extern int globalVar; Home home = func2(35.67, . . . 89.05); #endif func3(home); abc2.h : . . . #include ”abc1.h” } . . . Home func2(double, double); . . . abc3.h : #include ”abc1.h” . . . void func3(Home); (Preprocessor Statements) 15 / 18

  16. Conditional compilation (cont) . . . #if SYSTEMTYPE == LINUX . . . #elif SYSTEMTYPE == SOLARIS . . . #elif SYSSTEMTYPE == WINDOWS . . . #else . . . #endif . . . • If the system is LINUX, preprocessor gives the code block listed after LINUX test and before SOLARIS test to compiling phase → hence, the term conditional compilation (Preprocessor Statements) 16 / 18

  17. Undefining a #define #define ARRAYSIZE 20 . . . #undef ARRAYSIZE #define ARRAYSIZE 30 . . . #undef getchar int getchar(void) { . . . } . . . (Preprocessor Statements) 17 / 18

  18. Pragma Directives . . . #pragma setlocale(”dutch”) . . . . . . #pragma optimize(on) . . . #pragma optimize(off) . . . • pragma statement gives additional information to compiler (Preprocessor Statements) 18 / 18

Recommend


More recommend