ECE209_macros.pptx
ECE 209 Fall 2011 Macros
11/7/11$ 1$
C$Preprocessor$Macros$
• #define$
• macro$=$symbolic$abbrevia;on$for…$
• constants$
• code$fragments$
Read:
Pages 630-642, C Primer Plus
ECE 209 Fall 2011 Macros
11/7/11$ 2$
C Preprocessor CSource and
Header Files
C Preprocessor
Compiler
Source Code
Analysis
Target Code
Synthesis
Symbol Table
Linker
Executable
Image
Library
Object Files
First step in the
translation process.
Removes comments.
(Replaced with single space.)
Inserts text from other files.
#include
#include “file.h”
Conditionally removes
parts of code.
#if, #ifdef, #else
ECE 209 Fall 2011 Macros
11/7/11$ 3$
C Preprocessor CSource and
Header Files
C Preprocessor
Compiler
Source Code
Analysis
Target Code
Synthesis
Symbol Table
Linker
Executable
Image
Library
Object Files
Source-to-source transforms
• Only text-based transformations
• Happens before compilation
• Does not translate code into
machine instructions
When compiler “sees” code,
there are no comments,
no directives, no macros, etc.
ECE 209 Fall 2011 Macros
11/7/11$ 4$
Macro
A “macro” specifies a text substitution.
#define PI 3.14159
Wherever “PI” is found in the source code,
preprocessor will replace it with “3.14159”.
macro = same rules as C identifier
body = any constant string
macro replacement body
By convention, we use
all caps for macro names.
ECE 209 Fall 2011 Macros
11/7/11$ 5$
Macro Expansion
Expansion = process of replacing macro with body.
Body might contain other macros, which are also expanded.
Macro is a symbol, not part of another identifier or quoted
string, e.g.,
PIG does not get expanded into 3.14169G
“The value of PI is…” — PI does not get expanded.
printf(“The value of PI is %d.\n”, PI);
will print:
The value of PI is 3.14159.
ECE 209 Fall 2011 Macros
11/7/11$ 6$
Sample Code
#define ROW_SIZE 40 /* elements per row */
#define COL_SIZE 20 /* elements per column */
int main() {
…
int data[ROW_SIZE][COL_SIZE]; /* alloc. data array */
…
for (i=0; i
ECE 209 Fall 2011 Macros
11/7/11$ 8$
Macro with Arguments
When expanded, also replaces arguments with
text provided.
#define DOUBLE(X) 2*X
macro replacement body
argument
DOUBLE(2) expands to 2*2
DOUBLE(foo) expands to 2*foo
DOUBLE(x+y) expands to 2*x+y
DOUBLE(PI) expands to 2*3.14159
ECE 209 Fall 2011 Macros
11/7/11$ 9$
Danger!!
This is a text-based substitution.
The preprocessor doesn’t know anything about
types, precedence of operators, etc.
DOUBLE(x+y) expands to 2*x+y NOT 2*(x+y)
To guard against this sort of thing,
macros tend to use a LOT of parentheses:
#define DOUBLE(X) (2*(X))
ECE 209 Fall 2011 Macros
11/7/11$ 10$
Another Bad Example…
#define SQUARE(N) N*N
Suppose variable x has the value 4.
What value gets assigned to y in each of the
following statements?
y = SQUARE(x); /* x*x = 4*4 = 16 */
y = SQUARE(x+1); /* x+1*x+1 = 2*x+1 = 9 */
ECE 209 Fall 2011 Macros
11/7/11$ 11$
Yet Another Bad Example…
#define DOUBLE(N) N+N
Suppose variable x has the value 4.
What value gets assigned to y in each of the
following statements?
y = DOUBLE(x); /* x+x = 4+4 = 8 */
y = DOUBLE(x)*3; /* x+x*3 = 4+12 = 16 */
ECE 209 Fall 2011 Macros
11/7/11$ 12$
Multiple Arguments
#define MEAN(X,Y) (((X)+(Y))/2)
Strings
#define FAIL “Program failed.\n”
Spanning multiple lines…
A macro must fit on a single “logical” line of source
code. Use backslash (\) to continue on next line.
#define FAIL “Program encountered \
a fatal error.\n”
ECE 209 Fall 2011 Macros
11/7/11$ 13$
A Macro is NOT a Function
There is no function call code generated.
— There’s no JSR, no pushing/popping.
Arguments are not evaluated.
— They are used for text substitution.
There is no type checking of args.
A macro must fit on one (logical) line.
You can’t “step into” a macro in the debugger.
ECE 209 Fall 2011 Macros
11/7/11$ 14$
#define SQUARE(X) ((X)*(X))
int sq(int x) { return x*x; }
Which is more efficient? Why?
SQUARE(2) sq(2)
Suppose function foo() requires 1000’s of cycles to
execute. Which is more efficient? Why?
SQUARE(foo(1)) sq(foo(1))
ECE 209 Fall 2011 Macros
11/7/11$ 15$
Why use a macro?
A small piece of repeated code,
too small to justify a function definition,
but annoying to type over and over.
#define IS_ODD(X) ((X)&1)
#define HEX_DIGIT(X) \
(((X)>=’0′ && (X)<='9') \
|| ((X)>=’A’ && (X)<='F') \
|| ((X)>=’a’ && (X)<='f'))
#define NIBBLE(X,N) ((X)>>(4*(N))&0xff)
ECE 209 Fall 2011 Macros
11/7/11$ 16$
Why use a macro?
Constant value or expression that you want to
easily change, if necessary. Or that you just want
to give a symbolic name.
#define LEGAL_AGE 21
#define LEGAL_LIMIT 0.08
#define LOW_BITS_MASK 0xFF
#define TEST_LOW(N) ((N)&LOW_BITS_MASK != 0)