Macro Pitfalls; Misnesting; Operator Precedence Problems - Red Hat ENTERPRISE LINUX 3 - USING CPP Using Instructions

Using cpp, the c preprocessor
Hide thumbs Also See for ENTERPRISE LINUX 3 - USING CPP:
Table of Contents

Advertisement

Chapter 3. Macros

3.9. Macro Pitfalls

In this section we describe some special rules that apply to macros and macro expansion, and point
out certain cases in which the rules have counter-intuitive consequences that you must watch out for.

3.9.1. Misnesting

When a macro is called with arguments, the arguments are substituted into the macro body and the
result is checked, together with the rest of the input file, for more macro calls. It is possible to piece
together a macro call coming partially from the macro body and partially from the arguments. For
example,
#define twice(x) (2*(x))
#define call_with_1(x) x(1)
call_with_1 (twice)
==> twice(1)
==> (2*(1))
Macro definitions do not have to have balanced parentheses. By writing an unbalanced open paren-
thesis in a macro body, it is possible to create a macro call that begins inside the macro body but ends
outside of it. For example,
#define strange(file) fprintf (file, "%s %d",
...
strange(stderr) p, 35)
==> fprintf (stderr, "%s %d", p, 35)
The ability to piece together a macro call can be useful, but the use of unbalanced open parentheses
in a macro body is just confusing, and should be avoided.

3.9.2. Operator Precedence Problems

You may have noticed that in most of the macro definition examples shown above, each occurrence
of a macro argument name had parentheses around it. In addition, another pair of parentheses usually
surround the entire macro definition. Here is why it is best to write macros that way.
Suppose you define a macro as follows,
#define ceil_div(x, y) (x + y - 1) / y
whose purpose is to divide, rounding up. (One use for this operation is to compute how many
objects are needed to hold a certain number of
a = ceil_div (b & c, sizeof (int));
==> a = (b & c + sizeof (int) - 1) / sizeof (int);
This does not do what is intended. The operator-precedence rules of C make it equivalent to this:
a = (b & (c + sizeof (int) - 1)) / sizeof (int);
objects.) Then suppose it is used as follows:
char
27
int

Advertisement

Table of Contents
loading

This manual is also suitable for:

Enterprise linux 3

Table of Contents