I am trying to write a macro which returns the smallest value of several integers. When I compile the following code, it throws an error "expected expression". I don't know what's wrong there. Could anyone point out the issues with this code?
#define SMALLEST (nums, (ret_val), ...) \
do { \
int i, val; \
va_list vl; \
va_start(vl,nums); \
(*ret_val) = va_arg(vl, int); \
for (i = 1; i < nums; i++) \
{ \
val=va_arg(vl, int); \
if ((*ret_val) > val) \
(*ret_val) = val; \
} \
va_end(vl); \
} while(0)
int main ()
{
int nums = 3;
int ret_val = 0;
SMALLEST(nums, &ret_val, 1, 2, 3);
return 0;
}
I am just curious about how to do it with Macro.
I am just curious about how to do it with Macro.
You can't. va_list
is a way for a variadic function to access its arguments. What you have written is a variadic macro. They are not the same (in particular the variadic macro is still only a syntactic convenience that does not let you process individual arguments). The only way to do what you want is to call a variadic function of your own design inside the variadic macro (and then you might as well eliminate the macro).
However, if you really insist on using a variadic macro, it turns out that you are lucky that the same separator ,
is used in macro arguments and in array initializers, so you can try something like:
#define F(X, ...) \
do { \
int t[] = { __VA_ARGS__ }; \
for (int i = 0; i < sizeof t / sizeof t[0]; i++) \
… \
} while (0)
I don't think you can. From the gcc manual (https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html) the best you can do in a standard way is write __VA_ARGS__
, which will expand the arguments in place (for example to pass to a function).
It then goes on to define other non-standard extensions, which you might be able to use, but wouldn't be standard.
Why not do it with a function?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With