CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University...

34
CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson [email protected]

Transcript of CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University...

Page 1: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

CSc 352An Introduction to the C Preprocessor

Saumya DebrayDept. of Computer Science

The University of Arizona, [email protected]

Page 2: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

The C preprocessor and its role

2

cpp(C preprocessor)

cc1(C compiler)

sourceprogram

compiledcode

C compiler (e.g., gcc)

expandedcode

• expand some kinds of characters• discard whitespace and comments

– each comment is replaced with a single space

• process directives:– file inclusion (#include)– macro expansion (#define)– conditional compilation (#if, #ifdef, …)

text: Ch. 14

Page 3: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

#include

• Specifies that the preprocessor should read in the contents of the specified file– usually used to read in type definitions, prototypes, etc.– proceeds recursively

• #includes in the included file are read in as well

• Two forms:– #include <filename>

• searches for filename from a predefined list of directories• the list can be extended via “gcc –I dir”

– #include “filename”• looks for filename specified as a relative or absolute path

3

Page 4: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

#include : Example

4

a predefined include file that:• comes with the system• gives type declarations,

prototypes for library routines (printf)

where does it come from?– man 3 printf :

Page 5: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

#include: cont’d

• We can also define our own header files:– a header file has file-extension ‘.h’– these header files typically contain “public” information

• type declarations• macros and other definitions • function prototypes

– often, the public information associated with a code file foo.c will be placed in a header file foo.h

– these header files are included by files that need that public information

#include “myheaderfile.h”

5

Page 6: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Macros

• A macro is a symbol that is recognized by the preprocessor and replaced by the macro body

– Structure of simple macros:#define identifier replacement_list

– Examples:

#define BUFFERSZ 1024#define WORDLEN 64

6

Page 7: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Using simple macros

• We just use the macro name in place of the value, e.g.:

#define BUFLEN 1024#define Pi 3.1416…char buffer[BUFLEN];…area = Pi * r * r;

7

NOT: #define BUFLEN = 1024 #define Pi 3.1416;

Page 8: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Example 1

8

Page 9: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Example 2

9

we can “macroize” symbols selectively

Page 10: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Parameterized macros

• Macros can have parameters– these resemble functions in some ways:

• macro definition ~ formal parameters• macro use ~ actual arguments

– Form:#define macroName(arg1, …, argn) replacement_list

– Example:#define deref(ptr) *ptr#define MAX(x,y) x > y ? x : y

10

no space here!(else preprocessor will assume we’re defining

a simple macro

Page 11: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Example

11

Page 12: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Macros vs. functions

• Macros may be (slightly) faster– don’t incur the overhead of function call/return– however, the resulting code size is usually larger

• this can lead to loss of speed

• Macros are “generic”– parameters don’t have any associated type– arguments are not type-checked

• Macros may evaluate their arguments more than once– a function argument is only evaluated once per call

12

Page 13: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Macros vs. Functions: Argument Evaluation

• Macros and functions may behave differently if an argument is referenced multiple times:– a function argument is evaluated once, before the call– a macro argument is evaluated each time it is encountered

in the macro body.

• Example:

13

int dbl(x) { return x + x;}…u = 10; v = dbl(u++);printf(“u = %d, v = %d”, u, v);

prints: u = 11, v = 20

#define Dbl(x) x + x…u = 10; v = Dbl(u++);printf(“u = %d, v = %d”, u, v);

prints: u = 12, v = 21

Dbl(u++) expands to:u++ + u++

Page 14: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Properties of macros

• Macros may be nested– in definitions, e.g.:

#define Pi 3.1416#define Twice_Pi 2*Pi

– in uses, e.g.:#define double(x) x+x#define Pi 3.1416…if ( x > double(Pi) ) …

• Nested macros are expanded recursively

14

Page 15: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Pitfalls of nested macros

15

Oops!

Page 16: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

What happened?

16

textual replacement!

Page 17: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Avoiding the problem

17

Page 18: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

What happened

18

Page 19: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Header Files

• Have a file extension “.h”• Contain shared definitions

– typedefs– macros– function prototypes

• referenced via “#include” directives

19

Page 20: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Header files: example

20

Page 21: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

typedefs

• Allow us to define aliases for types• Syntax:

typedef old_type_name new_type_name;• new_type_name becomes an alias for old_type_name

• Example:– typedef int BasePay;– typedef struct node { int value; struct node *next; } node;

21

Page 22: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Example

22

defines “wcnode” as an alias for “struct wc”

we can use “wcnode” in place of“struct wc”

but not here, since “wcnode” has not yet

been defined

Page 23: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

What if a file is #included multiple times?

23

foo.h

bar1.h bar2.h

bar.c

Page 24: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Example of multiple inclusions

24

Page 25: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Problems with multiple inclusions

25

Page 26: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Solution to multiple inclusion problem

• Use conditional compilation to ensure that a header file is “really included” at most once– header file’s responsibility to protect itself from multiple-

inclusion problems– uses a conditional-compilation directive #ifndef– in effect sets a flag when a file is included so we don’t

include it again– relies on convention

• we need to understand it so we don’t break it

26

Page 27: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Conditional Compilation: #ifdef

#ifdef identifierline1

linen

#endif• macros can be defined by the compiler:

– gcc –D macroName– gcc –D macroName=definition

• macros can be defined without giving them a specific value, e.g.:– #define macroName

27

line1 … linen will be included if identifier has been defined as a macro; otherwise nothing will

happen.

Page 28: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Conditional Compilation: #ifndef

#ifndef identifierline1…linen

#endif

28

line1 … linen will be included if identifier is NOT defined as a macro; otherwise

nothing will happen.

Page 29: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Solution to multiple inclusion problem

The header file is written as follows:

#ifndef file_specific_flag#define file_specific_flag…contents of file…#endif

• file_specific_flag usually constructed from the name of the header file:

E.g.: file = foo.h flag = _FOO_H_– try to avoid macro names starting with ‘_’

29

indicates whether or not this file has been

included already

Page 30: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Another use of #ifdefs

• They can be useful for controlling debugging output– Example 1: guard debugging code with #ifdefs:

#ifdef DEBUG…debug message…#endif

– Example 2: use the debug macro to control what debugging code appears in the program:

#ifdef DEBUG#define DMSG(msg) printf(msg) // debugging output#else#define DMSG(msg) {} // empty statement#endif

30

straightforward, but needs discipline to use consistently

Page 31: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Example 1(a)

31

Page 32: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Example 1(b)

32

to address the “too many arguments to macro” problem

“too many arguments” issue resolved, but the macro

expansion isn’t working quite the way we want

Page 33: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Example 1(c)

33

Page 34: CSc 352 An Introduction to the C Preprocessor Saumya Debray Dept. of Computer Science The University of Arizona, Tucson debray@cs.arizona.edu.

Generalizing #ifdef

#if constant-expressionline1

…linen

#endif

line1 … linen included if constant-expression evaluates to a non-zero value

34

Common uses:• #if 1or• #if 0