Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS 2130 Lecture 4 C Preprocessor. Typical "Includes" #include.

Similar presentations


Presentation on theme: "CS 2130 Lecture 4 C Preprocessor. Typical "Includes" #include."— Presentation transcript:

1 CS 2130 Lecture 4 C Preprocessor

2 Typical "Includes" #include

3 Back to Hello World #include int main(void) { printf(“Hello, World!\n”); return EXIT_SUCCESS; } OK?

4 Doesn’t printf return something? printf(3) returns number of characters transferred Therefore >= 0: Success < 0: Failure Probably not worthwhile to check return value Could do this: (void)printf(… Which means ignore return value BUT THIS COULD BE A REAL BAD IDEA

5 Some simple streams By default we are supplied the following streams stdin: Keyboard stdout: Screen stderr: Screen

6 So we could do... if(printf(…) < 0) { fprintf(stderr,”printf failed\n”); /* perhaps exit here? */ } One slight problem!

7 So we could do... if(printf(…) < 0) { (void)fprintf(stderr,”printf failed\n”); /* perhaps exit here? */ } Does it make sense to use (void) in front of fprintf? Does it make sense to use (void) in front of fprintf?

8 Three Exceptions AllAll function return values must be checked except (void)fprintf(stderr,… (void)fflush(stderr); (void)exit(EXIT_FAILURE); WITHOUT FAIL!!!

9 How you should feel (for the rest of your life) if you forget to check a return value Darkness falls across the land The midnight hour is close at hand Creatures crawl in search of blood To terrorize your neighbor's hood And whosoever shall be found Without the soul for getting down Must stand and face the hounds of hell And rot inside a corpse's shell The foulest stench is in the air The funk of forty thousand years And grizzly ghouls from every tomb Are closing in to seal your doom And though you fight to stay alive Your body starts to shiver For no mere mortal can resist The evil of the 2130 killers

10 Getting out right now! exit(EXIT_FAILURE); Why not just: return EXIT_FAILURE;

11 Macro Processing Would like a simple way of performing if(printf(…) < 0) { (void)fprintf(stderr,”printf failed\n”); /* perhaps exit here? */ } Macro Processing could be the answer but first...

12 When Things Happen Key focus of CS 2130 is understanding when things happen During Translation (Compilation) During Execution

13 Translation (Compilation) 1. Lexical Analysis (Scanning) –Remove Comments –Find Keywords (Reserved Words) 2. Syntax Analysis –Check for structural correctness 3. Semantic Analysis –Concerned with meaning 4. Code Generation 5. Optimization –Time –Space –Global vs. Peephole

14 Translation (Compilation) 1. Lexical Analysis (Scanning) –Remove Comments –Find Keywords (Reserved Words) 2. Syntax Analysis –Check for structural correctness 3. Semantic Analysis –Concerned with meaning 4. Code Generation 5. Optimization –Time –Space –Global vs. Peephole Front End (Analysis) Back End (Synthesis) Primary Concern in CS 2130

15 Translation (Compilation) 1. Lexical Analysis (Scanning) –Remove Comments –Find Keywords (Reserved Words) 2. Syntax Analysis –Check for structural correctness 3. Semantic Analysis –Concerned with meaning 4. Code Generation 5. Optimization –Time –Space –Global vs. Peephole Parsing

16 Macro Processing When does it occur? –Before step 1. Lexical Analysis –Thus: 0. Macro Processing What is it? –Text substitution –Following precise rules In C, Macro Processing is done by the C Preprocessor –Takes c source file –Does macro processing –Passes results to C Compiler

17 Macro Processing? #define ONE 1 x = y + ONE; becomes x = y + 1; return DONE; remains unchanged

18 C Preprocessor in Action! /usr/lib/cpp gcc -E Both run c preprocessor sending output to stdout /usr/lib/cpp yourprogram.c > someFile.txt gcc -E yourprogram.c > someFile.txt

19 Macro Examples #include #include “defs.h” Looks in /usr/include for stdio.h inserts contents into source file Looks for defs.h in local directory and inserts contents into source file

20 Macro Examples #define EXIT_SUCCESS 0 Note: Not a constant const int foo = 42; Macro processing uses a symbol table technique

21 Symbol Table Used commonly in any translation operation Symbol NameSymbol Attributes footype, value, address, scope, lifetime, constant

22 Example #define EXIT_SUCCESS 0 return EXIT_SUCCESS;

23 Example #define EXIT_SUCCESS 0 return 0;

24 Why? EXIT_SUCCESS Meaningful self-documentation

25 Shooting oneself in the foot #define ONE 1 #define TWO ONE + ONE int x = ONE, y = TWO; becomes int x = 1, y = ONE + ONE; becomes int x = 1, y = 1 + 1;

26 Efficiency Clearly y = 2; is more efficient than y = 1 + 1;

27 WRONG!

28 When do things happen? Translation –“static” stuff Execution –“dynamic” stuff Preprocessor Here

29 More foot perforating int z = TWO * TWO; becomes int z = 1 + 1 * 1 + 1; Probably not what was intended!!! Parentheses are your friend #define TWO (ONE + ONE) #define ONE (1) /* OVERKILL */

30 Parentheses ANSI standard guarantees 32 levels of parentheses nesting* *enough to satisfy Mr. Scheme: Kurt Eiselt

31 More shootin’ #define SQUARE(X) (X * X) int z = SQUARE(2); int z = SQUARE(x + y); Fix: #define SQUARE(X) ((X) * (X)) cuddling OK?

32 NOT! z = SQUARE(x++); becomes z = ((x++) * (x++)); What’s the correct answer? z = x 2 z = (x + 1) 2 z = x * (x + 1) z = (x + 1) * (x + 2)

33 NOT! z = SQUARE(x++); becomes z = ((x++) * (x++)); What’s the correct answer? z = x 2 /* maybe */ z = (x + 1) 2 /* probably not */ z = x * (x + 1) /* maybe */ z = (x + 1) * (x + 2) /* Probably not */

34 Another Possibility Make SQUARE a function int square(int x) { return x * x; } Now it’s a win! z = square(x); z = square(x+y); z = square(x++); All work properly Or is it? Any downside?

35 What happens? /* Macro */ SQUARE(x). SQUARE(x). SQUARE(x) /* Function */ square(x). square(x). square(x)

36 What happens? /* Macro */ ((x) * (x)). ((x) * (x)). ((x) * (x))

37 What happens? /* Macro */ ((x) * (x)). ((x) * (x)). ((x) * (x)) /* Function */ pass parameter(s) call function. pass parameter(s) call function. pass parameter(s) call function. square function return

38 What happens? /* Macro */ ((x) * (x)). ((x) * (x)). ((x) * (x)) /* Function */ pass parameter(s) call function. pass parameter(s) call function. pass parameter(s) call function. square function return

39 What happens? /* Macro */ ((x) * (x)). ((x) * (x)). ((x) * (x)) /* Function */ pass parameter(s) call function. pass parameter(s) call function. pass parameter(s) call function. square function return

40 What happens? /* Macro */ ((x) * (x)). ((x) * (x)). ((x) * (x)) /* Function */ pass parameter(s) call function. pass parameter(s) call function. pass parameter(s) call function. square function return

41 What happens? /* Macro */ ((x) * (x)). ((x) * (x)). ((x) * (x)) /* Function */ pass parameter(s) call function. pass parameter(s) call function. pass parameter(s) call function. square function return

42 What happens? /* Macro */ ((x) * (x)). ((x) * (x)). ((x) * (x)) /* Function */ pass parameter(s) call function. pass parameter(s) call function. pass parameter(s) call function. square function return

43 What happens? /* Macro */ ((x) * (x)). ((x) * (x)). ((x) * (x)) /* Function */ pass parameter(s) call function. pass parameter(s) call function. pass parameter(s) call function. square function return

44 Macros vs. Functions Macros –Text substitution at Translation (compile) time –May have problems: e.g. square(x++) –Will work with different types due to operator overloading floats, doubles, ints, … –Difficult to implement if complex –Macro optimizes for speed. Why? Functions –Separate piece of code –Overhead of passing arguments and returning results via stack –Fixes ambiguity problems: e.g. square(x + y) or(x++) –Function optimizes for space. Why?

45 Macros vs. Functions If the goal is not clearly optimization for speed or time but rather somewhere in-between it’s difficult to know exactly which choice is correct. In any event: Don’t try and outwit the compiler! A better algorithm is more of an improvement that trying to write tricky code!!!

46 Inline Can write inline int square(int x) { return x*x; } Now square(a++) will work correctly with macro like performance. Why use inline? Compiler will make decision for you if inline omitted gcc -finline-functions

47 Questions?

48


Download ppt "CS 2130 Lecture 4 C Preprocessor. Typical "Includes" #include."

Similar presentations


Ads by Google