1 <!DOCTYPE HTML PUBLIC
"-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995-7 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
7 <link rev=
"owner" href=
"mailto:scs@eskimo.com">
8 <link rev=
"made" href=
"mailto:scs@eskimo.com">
9 <title>20.1: Function-Like Preprocessor Macros
</title>
10 <link href=
"sx6.html" rev=precedes
>
11 <link href=
"sx6b.html" rel=precedes
>
12 <link href=
"sx6.html" rev=subdocument
>
15 <H2>20.1: Function-Like Preprocessor Macros
</H2>
18 we've been defining simple preprocessor macros with simple values,
25 #define DATAFILE
"data.dat"
27 These macros always expand to constant text
29 the integer constant
<TT>200</TT>
30 and the string literal
<TT>"data.dat"</TT>, respectively)
31 wherever they're used.
33 it's also possible to define macros
34 which expand to text which is different each time,
38 These macros take arguments,
39 in much the same way that functions take arguments.
42 (the expansion of the macro,
43 like the action of the function)
44 depends in some way on the particular values passed to it as arguments.
45 The basic syntax of a function-like macro definition is
47 #define
<I>macroname
</I>(
<I>args
</I> )
<I>expansion
</I>
51 no space between
<I>macroname
</I> and the open parenthesis.
52 </p><p>We will illustrate the use of function-like macros with several examples.
53 </p><p>In a previous chapter,
54 we used the ``bitwise'' operators
55 <TT>&</TT>,
<TT>|
</TT>, and
<TT>~
</TT>
56 to manipulate individual bits
57 within an integer value or ``flags word.''
59 we defined several simple macros whose values were ``bitmasks'':
65 Then we used code like
69 to ``set the
<TT>DIRTY
</TT> bit,''
74 to clear the
<TT>DIRTY
</TT> bit,
81 these idioms become familiar enough that they can be read immediately,
82 but suppose we wanted to make them less cryptic.
83 Using the preprocessor,
84 we'll be able to set up macros so that we can write
90 CLEARBIT(flags, DIRTY);
94 if(TESTBIT(flags, DIRTY))
96 </p><p>The definition of the
<TT>SETBIT()
</TT> macro
99 #define SETBIT(x, b) x |= b
101 When a function-like macro is expanded,
102 the preprocessor keeps track
103 of the ``arguments'' it was ``called'' with.
106 SETBIT(flags, DIRTY);
108 we're invoking the
<TT>SETBIT()
</TT> macro
109 with a first argument of
<TT>flags
</TT>
110 and a second argument of
<TT>DIRTY
</TT>.
111 Within the definition of the macro,
112 those arguments were known as
<TT>x
</TT> and
<TT>b
</TT>.
113 So in the replacement text of the macro,
115 everywhere that
<TT>x
</TT> appears
116 it will be further replaced by (in this case)
<TT>flags
</TT>,
117 and everywhere that
<TT>b
</TT> appears it will be replaced by
122 SETBIT(flags, DIRTY);
124 will result in the expansion
128 Notice that the semicolon had nothing to do with macro expansion;
129 it appeared following the close parenthesis of the invocation,
130 and so shows up following the final expansion.
131 </p><p>Similarly, we can define the
<TT>CLEARBIT()
</TT>
132 and
<TT>TESTBIT()
</TT> macros like this:
134 #define CLEARBIT(x, b) x
&= ~b
135 #define TESTBIT(x, b) x
& b
137 Convince yourself that the invocations
139 CLEARBIT(flags, DIRTY);
143 if(TESTBIT(flags, DIRTY))
145 will result in the expansions
151 if(flags
& DIRTY)
154 </p><p>Just as for a regular function,
155 parameter names such as
<TT>x
</TT> and
<TT>b
</TT>
156 in a function-like macro definition are arbitrary;
157 they're just used to indicate where in the replacement text
158 the actual argument ``values'' should be plugged in.
159 Also, those parameter names are
<em>not
</em> looked for
160 within character or string constants.
161 If you had a macro like
163 #define XX(a, b) printf(
"%s is a %s\n", a, b)
167 XX(
"John",
"pumpkin-head");
171 #define XX(a, b) printf(
"%s is a %s\n",
"John",
"pumpkin-head");
173 It would
<em>not
</em> result in
175 #define XX(a, b) printf(
"%s is "John
" %s\n",
"John",
"pumpkin-head");
178 (in this case, anyway)
179 would not have been at all what you wanted.
180 </p><p>If we remember that
181 (other than being careful
182 not to expand macro arguments inside of string and character constants)
183 the preprocessor is otherwise pretty dumb and literal-minded,
184 we can see why there must not be a space
185 between the macro name and the open parenthesis
186 in a function-like macro definition.
189 #define SETBIT (x, b) x |= b
191 the preprocessor would think we were defining a simple macro,
192 named
<TT>SETBIT
</TT>,
196 <TT>(x, b) x |= b
</TT>
198 and every time it saw
<TT>SETBIT
</TT>,
199 it would replace it with
200 <TT>(x, b) x |= b
</TT>
202 (It would ignore any parentheses and arguments
203 that the invocation of
<TT>SETBIT
</TT> happened to be followed with;
205 after the incorrect definition,
208 SETBIT(flags, DIRTY);
212 (x, b) x |= b(flags, DIRTY);
214 where the
<TT>(flags, DIRTY)
</TT> part
215 passed through without modification,
216 along with the trailing semicolon.)
217 </p><p>There are a few potential pitfalls associated with preprocessor macros,
218 and with function-like ones in particular.
220 let's look at another example.
221 C has no built-in exponentiation operator;
222 if you want to square something,
223 the easiest way is usually to multiply it by itself.
224 Suppose that you got tired of writing
236 Knowing about function-like preprocessor macros,
237 you might be inspired to define a
<TT>SQUARE()
</TT> macro:
239 #define SQUARE(z) z * z
241 Now you can write things like
242 <TT>SQUARE(x)
</TT> and
<TT>SQUARE(a) + SQUARE(b)
</TT>,
243 and this seems like it will be workable and convenient.
245 what about that third example?
250 the simpleminded preprocessor will expand it to
255 the preprocessor doesn't evaluate arguments
256 the same way a function call would,
257 it just performs textual substitutions.
258 So in this last example,
259 the ``value'' of the macro parameter
<TT>z
</TT> is
261 and everywhere that a
<TT>z
</TT> had appeared in the replacement text,
262 the preprocessor fills in
<TT>x +
1</TT>.
263 But when the rest of the compiler sees the result,
264 it will give multiplication higher precedence,
266 and it will interpret the result as if you had written
270 which will
<em>not
</em> usually give you the result you wanted!
272 </p><p>How can we fix this problem?
273 We could forbid ourselves to ever ``call''
274 the
<TT>SQUARE()
</TT> macro
275 on an argument that wasn't a single constant or variable name,
276 but this seems like a harsh restriction.
277 A better solution is to play with the definition of the macro itself:
278 since the expansion we want is
282 we can achieve that by defining the macro like this:
284 #define SQUARE(z) (z) * (z)
292 y = (x +
1) * (x +
1);
295 </p><p>There's another problem, though:
304 and the rest of the compiler interprets this as
308 (Multiplication and division have the same precedence,
310 go from left to right.)
311 What can we do this time?
312 We could enclose the invocation of the
<TT>SQUARE()
</TT> macro
313 in extra parentheses,
318 but that seems like a real nuisance to remember.
319 A better solution is to build those extra parentheses
320 into the definition of the macro, too:
322 #define SQUARE(z) ((z) * (z))
330 we have a macro that's safe
331 against all of the troublesome invocations
333 </p><p>There's a
<em>third
</em> potential problem, though:
338 Even with all of our parentheses,
343 and this is a distinct no-no,
344 because we're incrementing
<TT>x
</TT> twice within the same expression.
345 We might end up with
<TT>y
</TT> containing the value
348 but it's somewhat more likely that we'll end up with
351 <TT>x * (x +
1)
</TT>,
353 (We're now worried not
355 about what the macro expands to,
356 but what the resultant expression
<em>evaluates
</em> to.)
358 since expressions like
<TT>x++ * x++
</TT>
359 are
<dfn>undefined
</dfn> according to the ANSI/ISO C Standard,
360 they can actually result in anything,
361 even complete nonsense.
362 So
<TT>SQUARE(x++)
</TT> simply isn't going to work.
363 (The explicit parentheses,
364 by the way, don't make the expression any
366 </p><p>There's no good fix for this third problem.
369 have to remember that when we invoke
372 the macro might expand one of its arguments multiple times,
373 so we had better not ever give it an argument with a side effect,
374 such as
<TT>x++
</TT>,
375 or else the side effect might end up happening multiple times,
376 with undefined results.
377 (That's one reason we always use capital letters for macro names,
378 to remind ourselves that they are special,
379 and that we might have to be careful when invoking them.)
380 </p><p>The other way around the third problem
381 is not to use a function-like preprocessor macro at all,
384 use a genuine function.
392 then we wouldn't have
<em>any
</em> of these problems.
394 then we'd have the limitation
395 that we could only use this
<TT>square
</TT> function
396 on arguments of a certain type,
397 in this case,
<TT>int
</TT>.
398 We could declare it as accepting and returning type
<TT>double
</TT>,
399 but then we might worry
400 that it was doing needless floating-point conversions
401 in the cases where we handed it integer values...)
402 </p><p>When should you use a function-like macro
403 and when should you use a real function?
405 it's safer to use real functions.
407 you use function-like macros
408 only when the code they expand to is quite small and simple,
409 and when defining and using a real function would for some reason be awkward,
410 or when the code will be executed so often
411 that the overhead of calling a real function
412 would significantly impact the program's efficiency.
413 </p><p>As an example of how a real function might be awkward,
414 notice that we couldn't write
<TT>SETBIT()
</TT>
415 and
<TT>CLEARBIT()
</TT> as conventional functions,
416 because functions can't modify their arguments,
417 yet
<TT>SETBIT()
</TT> and
<TT>CLEARBIT()
</TT>
420 <TT>SETBIT(flags, DIRTY)
</TT> modifies
<TT>flags
</TT>.)
421 </p><p>To summarize the important rules of this section,
423 whenever defining a function-like macro, remember:
424 <OL><li>Put parentheses around
425 each instance of each macro parameter in the replacement text.
426 <li>Put parentheses around
427 the entire replacement text.
428 <li>Capitalize the macro name to remind yourself that it is a macro,
429 so that you won't call it on arguments with side effects.
430 </OL>Remember, too, not to
431 put a space between the macro name
432 and the open parenthesis in the definition.
433 </p><p>Rewriting our first three examples to follow these rules,
436 #define SETBIT(x, b) ((x) |= (b))
437 #define CLEARBIT(x, b) ((x)
&= ~(b))
438 #define TESTBIT(x, b) ((x)
& (b))
440 (It's harder to see how
<TT>SETBIT()
</TT>
441 and
<TT>CLEARBIT()
</TT> might fail if they weren't parenthesized,
442 but unless you're really sure of yourself,
445 not to use the extra parentheses.)
446 </p><p>A few final notes about function-like preprocessor macros:
448 people try to write function-like macros
449 which are even more like functions
450 in that they expand to multiple statements;
452 this is considerably trickier than it looks
453 (at least, if it's not to fall victim to additional sets of pitfalls).
454 Also, people sometimes wish for macros
455 that take a variable number of arguments
456 (in much the same way that the
<TT>printf
</TT> function
457 accepts a variable number of arguments),
460 good way to do this, either.
465 <a href=
"sx6.html" rev=precedes
>prev
</a>
466 <a href=
"sx6b.html" rel=precedes
>next
</a>
467 <a href=
"sx6.html" rev=subdocument
>up
</a>
468 <a href=
"top.html">top
</a>
471 This page by
<a href=
"http://www.eskimo.com/~scs/">Steve Summit
</a>
472 //
<a href=
"copyright.html">Copyright
</a> 1996-
1999
473 //
<a href=
"mailto:scs@eskimo.com">mail feedback
</a>