Reputation: 1
Need max/min with unknown number of arguments, like :
#define MAX_N(first, second, remain...) MAX_N(((first)>(second)?(first):(second)), ##remain)
In my opinion, this will not keep expanding infinitely and should be accepted by compiler?
Unfortunately, I have to use pure C rather than C++.
Upvotes: 0
Views: 172
Reputation: 412
Why do you need a recursive macro? you can write a variadic min/max function like this:
#include <stdio.h>
#include <stdarg.h>
// credit for NUMARGS: https://stackoverflow.com/a/2124433/2889478
#define NUMARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int))
#define MAX(...) (max_variadic(NUMARGS(__VA_ARGS__), __VA_ARGS__))
int max_variadic(int narg, ...)
{
va_list args;
int pos = 0, max_val = 0;
va_start(args, narg);
while (narg--) {
int i = va_arg(args, int);
max_val = !pos ? i : i > max_val ? i : max_val;
pos++;
}
va_end(args);
return max_val;
}
int main(void)
{
int mx = MAX(4, 6, -1, 9, 2);
printf("%d", mx);
}
Upvotes: 0
Reputation: 222933
C 2018 6.10.3.4 2 says, about rescanning the result of macro replacement for further macros:
If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file’s preprocessing tokens), it is not replaced. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced…
Therefore, recursive macros are not possible, not even just for two levels, let alone indefinitely many.
It is possible to cause macros to be expanded multiple times by using other macros to expand them. As a simple example, after #define X Y Y
, X
will be replaced by two occurrences of Y
, each of which, if it is a defined macro, will be replaced—but separately, not recursively. This can be exploited to create macros that cause sone finitely limited number of expansions, but indefinitely many expansions are not possible.
Upvotes: 2