Module 05 Preprocessor and Macros in C

26
See through C Module 5 Macros and preprocessors Tushar B Kute http://tusharkute.com

description

The presentation given at PCCOE, Nigdi, Pune by Prof. Tushar B Kute in workshop on "See through C". http://tusharkute.com

Transcript of Module 05 Preprocessor and Macros in C

Page 1: Module 05 Preprocessor and Macros in C

See through C

Module 5

Macros and preprocessors

Tushar B Kutehttp://tusharkute.com

Page 2: Module 05 Preprocessor and Macros in C

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, …)

Page 3: Module 05 Preprocessor and Macros in C

#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: Module 05 Preprocessor and Macros in C

#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: Module 05 Preprocessor and Macros in C

#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: Module 05 Preprocessor and Macros in C

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: Module 05 Preprocessor and Macros in C

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: Module 05 Preprocessor and Macros in C

Example 1

8

Page 9: Module 05 Preprocessor and Macros in C

Example 2

9

we can “macroize” symbols selectively

Page 10: Module 05 Preprocessor and Macros in C

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: Module 05 Preprocessor and Macros in C

Example

11

Page 12: Module 05 Preprocessor and Macros in C

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: Module 05 Preprocessor and Macros in C

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: Module 05 Preprocessor and Macros in C

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: Module 05 Preprocessor and Macros in C

Header Files

• Have a file extension “.h”

• Contain shared definitions

– typedefs– macros– function prototypes

• referenced via “#include” directives

15

Page 16: Module 05 Preprocessor and Macros in C

Header files: example

16

Page 17: Module 05 Preprocessor and Macros in C

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;

17

Page 18: Module 05 Preprocessor and Macros in C

Example

18

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 19: Module 05 Preprocessor and Macros in C

What if a file is #included multiple times?

19

foo.h

bar1.h bar2.h

bar.c

Page 20: Module 05 Preprocessor and Macros in C

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

20

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

happen.

Page 21: Module 05 Preprocessor and Macros in C

Conditional Compilation: #ifndef

#ifndef identifier

line1

linen

#endif

21

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

nothing will happen.

Page 22: Module 05 Preprocessor and Macros in C

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 ‘_’

22

indicates whether or not this file has been

included already

Page 23: Module 05 Preprocessor and Macros in C

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

23

straightforward, but needs discipline to use consistently

Page 24: Module 05 Preprocessor and Macros in C

Generalizing #ifdef

#if constant-expression

line1

linen

#endif

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

24

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

Page 25: Module 05 Preprocessor and Macros in C

__LINE__ current line number of the source file__FILE__ name of the current source file__TIME__ time of translation__STDC__ 1 if the compiler conforms to ANSI C

printf("working on %s\n", __FILE__);

Predefined Macros

Page 26: Module 05 Preprocessor and Macros in C

Adapted originally from:

CSc 352An Introduction to the C Preprocessor

Saumya Debray

Dept. of Computer Science

The University of Arizona, Tucson

[email protected]

Thank you

This presentation is created using LibreOffice Impress 3.6.2.2