Writing this as a macro is easy, not that it is always a good idea.
In this case, I think it is better to write a macro that builds a function, instead of trying to do the work directly inline:
- Take your non-generic code.
- Add
\
at the end of every line, because macros are one-line only. - Add
#define NAME(...) \
at the beginning. - Replace the macro arguments where needed.
- Do not forget the extra parenthesis, if needed.
The result would be along the lines of:
#define GET_MYSTUFF(TYPE, FIELD) \
TYPE* get_mystuff_##FIELD(struct mystuff *array, int n) \
{ \
int i; \
TYPE *res_array; \
res_array = malloc(n*sizeof(TYPE)); \
for(i=0;i<n;i++) { \
res_array[i] = array[i].FIELD; \
} \
return res_array; \
}
Now you create all your functions with:
GET_MYSTUFF(int, a)
GET_MYSTUFF(int, b)
GET_MYSTUFF(int, c)
You can even add the input array type as another parameter for the macro, but that is left as an exercise to the reader.
UPDATE: Note that this macro expand to a function definition, and you should not define your functions in the header file or else you will have duplicated definition errors. There are several solutions, pick your best:
- Make your functions static (
static TYPE* get_mystuff_##FIELD(...
). This way every compilation unit that includes your function will get a copy of the function. Move the definition of the functions to a
mystuff.c
file, and write only the function prototypes inmystuff.h
. You can write these prototypes manually or create a macro for that:#define GET_MYSTUFF_PROTO(TYPE, FIELD) TYPE* get_mystuff_##FIELD(struct mystuff *array, int n);
With a bit of extra work, and if you want a bit of fun, you can use X_Macros!
mystuff.h
#ifndef GET_MYSTUFF
#define GET_MYSTUFF(TYPE, FIELD) \
TYPE* get_mystuff_##FIELD(struct mystuff *array, int n);
#endif
GET_MYSTUFF(int, a)
GET_MYSTUFF(int, b)
GET_MYSTUFF(int, c)
mystuff.c
/* include for prototypes */
#include "mystuff.h"
#undef GET_MYSTUFF
#define GET_MYSTUFF(TYPE, FIELD) \
TYPE* get_mystuff_##FIELD(struct mystuff *array, int n) \
{ \
int i; \
TYPE *res_array; \
res_array = malloc(n*sizeof(TYPE)); \
for(i=0;i<n;i++) { \
res_array[i] = array[i].FIELD; \
} \
return res_array; \
}
/* include for definitions */
#include "mystuff.h"