Title: Preprocessor Directives
1- Preprocessor Directives
- Reading KR 4.11
2Introduction
- The preprocessor uses text substitution to revise
source code. - You can use the -E option with gcc to see the
output of the preprocessor. - Once the preprocessor completes text
substitution, the revised text is processed by
the compiler.
3Introduction (continued)
- The most common use of the preprocessor is to
define constants. - E.g. define PI 3.1415926
- Other uses are parameterized macros, and
conditional compilation.
4Macros with Parameters
- Form
- define macro_name(parameter list) macro body
- Note there must be no space between the name
and the left parenthesis. - Example
5Macros with Parameters (continued)
define LABEL_PRINT_INT(label, num) printf("s
d", (label), (num)) void main(void) int
i 5 LABEL_PRINT_INT("rabbit", i) The
preprocessor replaces the above with
printf("s d", ("rabbit"), (i))
6Macros with Parameters (continued)
- Multiple substitution is also possible. For
example
define CONTROL "d\n" define
PRINT_INT(i) printf(CONTROL, (i)) define
PRINT_POS_INT(i) if ((i) gt 0) PRINT_INT(i) void
main(void) PRINT_POS_INT(10) The
resulting expansion is if ((10) gt 0)
printf("d\n", (10))
7Macros with Parameters (continued)
Macro Function
- Macro code is repeated through the program code
by text substitution. - Larger program size.
- Faster execution since code is executed in line.
- Function code is stored only once in a program
execution will go to a function, then return to
the calling code. - Smaller program size.
- Slower execution.
8Macros with Parameters (continued)
- Since memory is inexpensive relative to processor
speed, it might seem that macros are preferred to
functions. However - Macros may have unintended side effects,
resulting in bugs which are difficult to debug
(see example below). - In general, use functions instead of macros.
- Older code may use parameterized macros a lot, so
it is important to understand their use.
9Macros with Parameters (continued)
- Example of unintended side effects
define SQUARE(x) ((x) (x)) void
main(void) int a 3, b b
SQUARE(a) The following expansion takes
place b ((a) (a)) which results in
a 5 and b 12
10Macros with Parameters (continued)
int square(int x) return (x x) void
main(void) int a 3, b b
square(a) which results in a 4 and b 9
11Conditional Compilation
- Is the technique of using the preprocessor to
include or omit code, depending on defined
conditions. - This is useful when
- A program runs on different computer systems, or
is distributed in more than one version. - A program contains debugging code that needs to
be turned on or off during development.
12Conditional Compilation (continued)
- General form if defined(constant1) co
de to be compiled elif defined(constant2)
other code to be compiled - else
- default code to be compile
- endif
13Conditional Compilation (continued)
- Example
-
- define LINUX
- ..
- if defined(LINUX)
- system(clear) uses Linux system function
- elif defined(DOS)
- system(cls) uses DOS system function
- endif
14Conditional Compilation (continued)
- Note that
- ifdef is the same as if defined()
- ifndef is the same as if !defined()
- Use the -D option when compiling if you want to
turn on particular code. - For example
- gw -o myprog -DDEBUG myprog.c
15Conditional Compilation (continued)
myprog.c void main(void) ... if
defined(DEBUG) ... // Code here
is compiled in endif ...
16Conditional Compilation (continued)
- You can temporarily comment out large sections of
code by using if 0 and endif. - This is useful, since comments in C dont nest.
- You can uncomment this code by changing the 0 to
a 1. - Example
17Conditional Compilation (continued)
... if 0 . // Code here is
temporarily commented . // out,
regardless of comments that . // already
exist endif ...
18Conditional Compilation (continued)
- Preprocessor directives can nest if
defined(DEBUG) ... if
defined(ALPHA) ... endif
... endif
19Divisions of Program
- A program may include one or more modules, and
each module may contain one or more of the
following type of files - Implementation files
- Example myfile.c, or myfile.cpp
- Interface files
- Example myfile.h
20Divisions of Programs
- File organization in a C/C Program
Program
Module 1
Module 2
File1.c Or File1.cpp
File1.h
File2.c Or File2.cpp
File2.h
21Divisions of Programs - Example
- // myprog.c file (an implementation file)
- include ltstdio.hgt
- include funcs.h
- Int main()
-
- int a 4, b7, c5
- printf( Largest is d, largest(a, b, c))
- printf( \nAverage is f., average(a, b,
c) - return 0
22Divisions of Programs - Example
- // funcs.h file (an interface)
- ifndef XYZ
- define XYZ
- int largest (int x, int y, int z)
- float average (int x, int y, int z)
- endif
23Divisions of Programs - Example
// funcs.c file (an implementation)
- include funcs.h
- Int largest (int x, int y, int z)
-
- int result x
- if (y gt result)
- result y
- if (z gt result)
- result z
- return result
float average (int x, int y, int z) float
result result double(xyz)/3.0 return
result
24Divisions of Programs
- Interface part of a program normally contains
- Function prototypes
- Constants
- Definition of abstract data types, such as
structures, and classes - Other Preprocessor directives such as include
statements - Macros
- Etc.
- Implementation part of a program normally
contains - Info about how the module does its.