I'm trying to decide whether to implement certain operations as macros or as functions.
Say, just as an example, I have the following code in a header file:
extern int x_GLOB;
extern int y_GLOB;
#define min(x,y) ((x_GLOB = (x)) < (y_GLOB = (y))? x_GLOB : y_GLOB)
the intent is to have each single argument computed only once (min(x++,y++)
would not cause any problem here).
The question is: do the two global variables pose any issue in terms of code re-entrancy or thread safeness?
I would say no but I'm not sure.
And what about:
#define min(x,y) ((x_GLOB = (x)), \
(y_GLOB = (y)), \
((x_GLOB < y_GLOB) ? x_GLOB : y_GLOB)
would it be a differnt case?
Please note that the question is not "in general" but is related to the fact that those global variables are used just within that macro and for the evaluation of a single expression.
Anyway, looking at the answers below, I think I can summarize as follows:
It's not thread safe as nothing guarantees that a thread is suspended "in the middle" of the evaluation of an expression (as I hoped instead)
The "state" those globals represent is, at least, the internal state of the "min" operation and preserving that state would, again at least, require to impose restrictions on how the function can be called (e.g. avoid min(min(1,2),min(3,1)).
I don't think using non-portable constructs is a good idea either so I guess the only option is to stay on the safe side an implement those cases as regular functions.