Many C programs define a macro `min
', for ``minimum'', like this:
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
When you use this macro with an argument containing a side effect, as shown here,
next = min (x + y, foo (z));
it expands as follows:
next = ((x + y) < (foo (z)) ? (x + y) : (foo (z)));
where `x + y
' has been substituted for `X
' and `foo (z)
'
for `Y
'.
The function `foo
' is used only once in the statement as it appears
in the program, but the expression `foo (z)
' has been substituted
twice into the macro expansion. As a result, `foo
' might be called
two times when the statement is executed. If it has side effects or
if it takes a long time to compute, the results might not be what you
intended. We say that `min
' is an unsafe macro.
The best solution to this problem is to define `min
' in a way that
computes the value of `foo (z)
' only once. The C language offers no
standard way to do this, but it can be done with GNU C extensions as
follows:
#define min(X, Y) \ ({ typeof (X) __x = (X), __y = (Y); \ (__x < __y) ? __x : __y; })
If you do not wish to use GNU C extensions, the only solution is to be
careful when using the macro `min
'. For example, you can
calculate the value of `foo (z)
', save it in a variable, and use that
variable in `min
':
#define min(X, Y) ((X) < (Y) ? (X) : (Y)) ... { int tem = foo (z); next = min (x + y, tem); }
(where we assume that `foo
' returns type `int
').
Packaging copyright © 1988-2000 OAR Corporation
Context copyright by each document's author. See Free Software Foundation for information.