I'd like to define a function like MACRO . i.e.
#define foo(x)\
#if x>32\
x\
#else\
(2*x)\
#endif
that is,
if x>32, then foo(x) present x
else, foo(x) present (2*x)
but my GCC complains about:
int a = foo(31);
I think C preprocessor should be handle this correctly. since at compile time, it knows x=33
. it could replace foo(33)
with (2*33)
You can as follows
But that evaluates
x
multiple times. You can instead create a static function, which is cleanerThen you are also able to pass things to
foo
that have side effects, and have the side effect happen only one time.What you have written is using the
#if
,#else
and#endif
preprocessor directives, but you need to use language constructs if you pass variables to the macro and want to evaluate their values. Usingif
, andelse
statements as in the actual language constructs don't work either, because control flow statements don't evaluate to values. In other words, an if statement is steering control flow only ("if A, then execute B, else execute C"), not evaluating to any values.Consider:
x is not known at compile time.
Expands out to
That's how C macros work, via simple, dumb substitution. If you expect gcc to do anything more complex or intelligent with them, then your expectation is erroneous.
Given that, it's easy to see why your code won't work. An alternative that would suffice for this example would be:
On the other hand, I would question whether macros are really the appropriate tool for such a thing to begin with. Just put it in the function and the compiler will inline the code if it thinks it will speed it up.
The problem is not about the theory: provided that you, for some reason, want to have a macro that expands differently according to the value of a parameter passed to it, and this parameter is a constant, known to the macro preprocessor, there's no reason why it couldn't work... for a generic macro processor... But cpp unluckly does not allow the presence of other macro processor "commands" into a macro definition...
So your
does not expand to
where X is the known parameter (so change X to e.g. 31), which requires another pass by the preprocessor.
Moreover newlines are ignored, while they are important for such an use; otherwise, the following could be considered as a trick (that need another preprocessing pass however)
that with
foo(20,#)
produceswhich would work, if it would be
... but it is not (and as said, the output of the preprocessor must be feeded to the preprocessor again...)
So my answer is that if you need these things, you can't use the C preprocessor; you should use a uncommon (not standard?) C preprocessor, or just another macro processor, and if you need the sort of things that "cpp" has to "integrate" itself with C, then you can't use a generic one (like M4) so easily...