240-491 adv. unix:pre/111 advanced unix v objectives of these slides: look at the features of the c...
DESCRIPTION
Adv. UNIX:pre/ Preprocessor Features v The preprocessor is part of the compiler –it modifies the C program before the program is compiled v The modifications involve text substitution –text in the program is replaced by other text continuedTRANSCRIPT
240-491 Adv. UNIX:pre/11 1
Advanced UNIXAdvanced UNIX
Objectives of these slides:Objectives of these slides:– look at the features of the C preprocessorlook at the features of the C preprocessor
240-491 Special Topics in Comp. Eng. 1Semester 2, 2000-2001
11. The Preprocessor
240-491 Adv. UNIX:pre/11 2
OverviewOverview
1.1. Preprocessor Features Preprocessor Features2.2. Including Files Including Files3.3. Symbolic Constants Symbolic Constants4.4. Macros Macros5.5. Conditional Compilation Conditional Compilation
240-491 Adv. UNIX:pre/11 3
1. Preprocessor Features1. Preprocessor Features
The preprocessor is part of the compilerThe preprocessor is part of the compiler– it modifies the C program it modifies the C program beforebefore the program is the program is
compiledcompiled
The modifications involve text The modifications involve text substitutionsubstitution– text in the program is replaced by other texttext in the program is replaced by other text
continued
240-491 Adv. UNIX:pre/11 4
Substitution is actually based on replacing C Substitution is actually based on replacing C tokenstokens by other text. by other text.
Examples of tokens in a line of C codeExamples of tokens in a line of C code– the code:the code:
x = inc(foo);x = inc(foo);– the tokens:the tokens:x = inc ( foo ) ;x = inc ( foo ) ;
240-491 Adv. UNIX:pre/11 5
1.1. Main Kinds of Substitutions1.1. Main Kinds of Substitutions
File InclusionFile Inclusion Symbolic ConstantsSymbolic Constants MacrosMacros Conditional CompilationConditional Compilation
240-491 Adv. UNIX:pre/11 6
1.2. Seeing the Substitution1.2. Seeing the Substitution It is possible to execute only the preprocessor part of It is possible to execute only the preprocessor part of gccgcc: :
$ gcc $ gcc -E-E examp.c examp.c
This call to This call to gccgcc will output the modified version of will output the modified version of examp.cexamp.c
– can be used for checking that the right substitutions are can be used for checking that the right substitutions are occurringoccurring
240-491 Adv. UNIX:pre/11 7
2. Including Files 2. Including Files (#include)(#include)
Some examples:Some examples:#include <stdio.h> /* from /usr/include */#include <stdio.h> /* from /usr/include */#include “mydefs.h” /* from current dir */#include “mydefs.h” /* from current dir */
#include <sys/file.h> /* from /usr/include/sys */#include <sys/file.h> /* from /usr/include/sys */
Each #include line in the program will bereplaced by the contents of the named header file.
240-491 Adv. UNIX:pre/11 8
2.1. What’s in a header file?2.1. What’s in a header file? Headers are C code (so Headers are C code (so have a lookhave a look).). Typical code:Typical code:
– symbolic constant definitions (symbolic constant definitions (#define#define lines) lines)– typedeftypedef declarations declarations– externextern declarations (see later)declarations (see later)– function prototypesfunction prototypes
You will write your own header files when coding large, You will write your own header files when coding large, multiple file programs multiple file programs – see latersee later
240-491 Adv. UNIX:pre/11 9
3. Symbolic Constants3. Symbolic Constants (#define) (#define) Some examples:Some examples:
#define TRUE 1#define TRUE 1#define FALSE 0#define FALSE 0#define SIZE 10#define SIZE 10#define MAX (SIZE*2 + 1)#define MAX (SIZE*2 + 1)
Common mistake – adding a ‘Common mistake – adding a ‘;;’’# define SIZE 10;# define SIZE 10;while (x < SIZE) ...while (x < SIZE) ...
becomesbecomeswhile (x < 10while (x < 10;;) ...) ...
The preprocessor replaces SIZEby 10;
a constantdefined usinganother constant
240-491 Adv. UNIX:pre/11 10
4. Macros4. Macros Some examples:Some examples:
#define sum(x, y)#define sum(x, y) ((x) + (y)) ((x) + (y))#define cube(x)#define cube(x) ((x) * (x) * (x)) ((x) * (x) * (x))#define print(str)#define print(str) { printf(“%s\n”, { printf(“%s\n”, str); }str); }
Use:Use: Translation:Translation:c = sum(a, b);c = sum(a, b); c = ((a) + (b));c = ((a) + (b));y = cube(a);y = cube(a); y = ((a) * (a) * (a));y = ((a) * (a) * (a));print(argv[1]);print(argv[1]); { printf(“%s\n”, argv[1]); }{ printf(“%s\n”, argv[1]); }
the macro body
240-491 Adv. UNIX:pre/11 11
4.1. Rules you 4.1. Rules you MustMust Follow Follow
1. Don’t place ‘;’s at the end of a macro body.1. Don’t place ‘;’s at the end of a macro body. 2. Bracket every parameter in the macro body.2. Bracket every parameter in the macro body. 3. Bracket the entire macro body.3. Bracket the entire macro body. 4. Avoid side-effects in macro calls.4. Avoid side-effects in macro calls. 5. Add braces around multiple statements in a 5. Add braces around multiple statements in a
macro body; have a ‘;’ after every statement.macro body; have a ‘;’ after every statement.
When in doubt: add some brackets
240-491 Adv. UNIX:pre/11 12
4.2. Macros are 4.2. Macros are notnot Functions Functions
A macro ‘call’ is textually A macro ‘call’ is textually replacedreplaced by the by the macro body inside the preprocessor.macro body inside the preprocessor.
There is There is no overheadno overhead of a function call at run- of a function call at run-time.time.
Macro replacement causes the Macro replacement causes the sizesize of the of the program to increase.program to increase.
LotsLots of tricky errors are possible. of tricky errors are possible.
240-491 Adv. UNIX:pre/11 13
4.3. Multi-line Macros4.3. Multi-line Macros
Big macros use ‘\’ to run over multiple lines:Big macros use ‘\’ to run over multiple lines:
#define swap_int(s1, s2) { int temp; \#define swap_int(s1, s2) { int temp; \ temp = s1; \ temp = s1; \ s1 = s2; \ s1 = s2; \ s2 = temp; } s2 = temp; }
240-491 Adv. UNIX:pre/11 14
4.4. Some Common Errors4.4. Some Common Errors
1. Including space after the macro name.1. Including space after the macro name.
2. Missing parameter brackets.2. Missing parameter brackets.
3. Missing macro body brackets.3. Missing macro body brackets.
4. Including side effects in macros.4. Including side effects in macros.
240-491 Adv. UNIX:pre/11 15
4.4.1. Space after macro name4.4.1. Space after macro name
Example:Example:#define abs (x) ((x)> 0) ? (x) : (-(x)))#define abs (x) ((x)> 0) ? (x) : (-(x)))/* WRONG *//* WRONG */
Use:Use:x = x = absabs(2)(2);;
Expansion:Expansion:x = x = (x) ((x)> 0) ? (x) : (-(x)))(x) ((x)> 0) ? (x) : (-(x)))(2);(2);
replaced by
space after abs
240-491 Adv. UNIX:pre/11 16
4.4.2. Missing parameter brackets4.4.2. Missing parameter brackets Example:Example:
#define cube(x) #define cube(x) x * x * xx * x * x /* WRONG *//* WRONG */
Use:Use:y = cube(z + 1);y = cube(z + 1);
Expansion:Expansion: y = z + 1 * z + 1 * z + 1;y = z + 1 * z + 1 * z + 1;
same as:same as:y = z + (1 * z) + (1 * z) + 1;y = z + (1 * z) + (1 * z) + 1;
no bracketsaround the x's
continued
240-491 Adv. UNIX:pre/11 17
CorrectCorrect Version: Version:#define cube(x) #define cube(x) ((((xx)) * * ((xx)) * * ((xx))))
Use:Use:y = cube(z + 1);y = cube(z + 1);
Expansion:Expansion:y = (y = (((z + 1z + 1)) * * ((z + 1z + 1)) * * ((z + 1z + 1))););
240-491 Adv. UNIX:pre/11 18
4.4.3. Missing macro body brackets4.4.3. Missing macro body brackets Example:Example:
#define inc(x)#define inc(x) (x) + 1(x) + 1 /* WRONG *//* WRONG */
Use:Use:p = 3 * inc(q);p = 3 * inc(q);
Expansion:Expansion: p = 3 * (q) + 1;p = 3 * (q) + 1;
same as:same as:p = (3 *(q)) + 1;p = (3 *(q)) + 1;
no brackets aroundthe entire macro body
continued
240-491 Adv. UNIX:pre/11 19
CorrectCorrect version: version:#define inc(x)#define inc(x) (((x) + 1(x) + 1))
Use:Use:p = 3 * inc(q);p = 3 * inc(q);
Expansion:Expansion:p = 3 * p = 3 * (((q) + 1(q) + 1));;
240-491 Adv. UNIX:pre/11 20
4.4.4. Side effects4.4.4. Side effects Example:Example:
#define cube(x)#define cube(x) ((x) * (x) * (x))((x) * (x) * (x))
Use:Use:int a = 2;int a = 2;c = cube(a++);c = cube(a++);
Expansion:Expansion:int a = 2;int a = 2;c = ((a++) * (a++) * (a++))c = ((a++) * (a++) * (a++))
a's value isside-effectedthree times
240-491 Adv. UNIX:pre/11 21
4.5. More Examples4.5. More Examples /* macros instead of functions *//* macros instead of functions */
#define max(x, y)#define max(x, y) ((x) > (y) ? (x) : (y))((x) > (y) ? (x) : (y))#define sign(x)#define sign(x) ((x) < 0 ? -1 : \((x) < 0 ? -1 : \
((x) > 0 ? 1 : 0))((x) > 0 ? 1 : 0))
/* macros for control flow *//* macros for control flow */#define forever#define forever for(;;)for(;;)#define repeat#define repeat do {do {#define until(x)#define until(x) } while (!(x))} while (!(x))
/* nicer names *//* nicer names */#define TRUE#define TRUE11#define FALSE#define FALSE 00
continued
to beused asa pair
240-491 Adv. UNIX:pre/11 22
/* graphics macro *//* graphics macro */#define line(x1,y1,x2,y2) { moveto(x1, y1) ; \#define line(x1,y1,x2,y2) { moveto(x1, y1) ; \
lineto(x2, y2); } lineto(x2, y2); }
/* macro instead of function, with type info *//* macro instead of function, with type info */#define swap(x, y, TYPE)#define swap(x, y, TYPE){ TYPE temp; \{ TYPE temp; \
temp = x; \ temp = x; \ x = y; \ x = y; \ y = temp; } y = temp; }
/* hide pointers without using functions *//* hide pointers without using functions */#define LEFT(ptr)#define LEFT(ptr) (ptr->left)(ptr->left)#define RIGHT(ptr)#define RIGHT(ptr)(ptr->right)(ptr->right)#define DATA(ptr)#define DATA(ptr) (ptr->data)(ptr->data)
240-491 Adv. UNIX:pre/11 23
4.6. Undefining4.6. Undefining
Cancel a definition:Cancel a definition:#undef name#undef name
– applies from this line in the text downwardsapplies from this line in the text downwards
Can redefine later:Can redefine later:#define name 10#define name 10
240-491 Adv. UNIX:pre/11 24
5. Conditional Compilation5. Conditional Compilation
Specify which blocks of code to Specify which blocks of code to compilecompile– some parts of the program can be some parts of the program can be ignoredignored
by the compilerby the compiler
Used for debugging and portability.Used for debugging and portability.
240-491 Adv. UNIX:pre/11 25
5.1. If Tests5.1. If Tests
General format:General format:#if#if expression expression
...... /* code to be included if /* code to be included if expression is true */ expression is true */
#endif#endif
Expressions are C-like, but can only refer to Expressions are C-like, but can only refer to symbolic constants and/or macros.symbolic constants and/or macros.
240-491 Adv. UNIX:pre/11 26
ExamplesExamples#define MAX 9#define MAX 9 : :#if#if MAX < 10 MAX < 10
........ /* code to include *//* code to include */#endif#endif
#define X #define X 55#define Y#define Y 77#define DEBUG 2#define DEBUG 2 : :#if#if X < Y && DEBUG == 1 X < Y && DEBUG == 1
... ... /* code to include */ /* code to include */ #endif#endif
240-491 Adv. UNIX:pre/11 27
Leaving Out CodeLeaving Out Code
Example:Example:##if if 00
...... /* lines of code to /* lines of code to be left out */ be left out */
#endif#endif
Useful for commenting out lines that Useful for commenting out lines that contain lots of commentscontain lots of comments– cannot nest comments in Ccannot nest comments in C
240-491 Adv. UNIX:pre/11 28
5.2. Multi-way Branches5.2. Multi-way Branches
Format:Format:#if expr1#if expr1
......#elif#elif expr2 expr2
......#elif expr3#elif expr3
...... : :#else#else
......#endif#endif
240-491 Adv. UNIX:pre/11 29
5.3. Definition Test5.3. Definition Test
#ifdef#ifdef name name Test if Test if namename defined defined#ifndef#ifndef name name Test if Test if namename notnot defined defined
Used for debugging:Used for debugging:#define DEBUG#define DEBUG : :#ifdef DEBUG#ifdef DEBUG printf(“Some debug message\n”): printf(“Some debug message\n”):#endif#endif
continued
240-491 Adv. UNIX:pre/11 30
Or:Or:#define DEBUG 1#define DEBUG 1 : :#if DEBUG == 1#if DEBUG == 1 printf(“Some debug message\n”); printf(“Some debug message\n”);#endif#endif
In this version, we must supply a value for In this version, we must supply a value for DEBUG.DEBUG.
continued
240-491 Adv. UNIX:pre/11 31
Prevent multiple includes:Prevent multiple includes:#ifndef#ifndef INCLUDED_TYPES INCLUDED_TYPES #define INCLUDE_TYPES #define INCLUDE_TYPES #include “types.h” #include “types.h”#endif#endif
Implement version differences:Implement version differences:#ifdef#ifdef UNIX UNIX char *version = “UNIX version”; char *version = “UNIX version”;#else#else char *version = “DOS version”; char *version = “DOS version”;#endif#endif
only include types.hif INCLUDE_TYPESisn't already defined
240-491 Adv. UNIX:pre/11 32
5.4. Creating Symbolic Constants5.4. Creating Symbolic Constants
Can use Can use #define#define
oror Create (and initialise) on the command line:Create (and initialise) on the command line:
$ gcc $ gcc -DDEBUG-DDEBUG -o examp examp.c -o examp examp.c/* define DEBUG *//* define DEBUG */
$ gcc $ gcc -DMAX=2-DMAX=2 -o foo foo.c -o foo foo.c/* define MAX with value 2 *//* define MAX with value 2 */
240-491 Adv. UNIX:pre/11 33
5.5. Error Reporting5.5. Error Reporting (#error) (#error)
Example:Example:#ifndef UNIX#ifndef UNIX #error#error UNIX version not chosen. UNIX version not chosen.#endif#endif
Or:Or:#if #if !defined!defined(UNIX)(UNIX) #error#error UNIX version not chosen UNIX version not chosen#endif#endif