[ACCEPTED]-How can I generate a list via the C preprocessor (cpp)?-c-preprocessor
The normal way of doing this with the preprocessor 4 is to define all the functions in a macro 3 that takes another macro as an argument, and 2 then use other macros to extract what you 1 want. For your example:
#define FUNCTION_TABLE(F) \
F(f1, { some code }) \
F(f2, { some code }) \
F(f3, { some code }) \
:
F(f99, { some code }) \
F(f100, { some code })
#define DEFINE_FUNCTIONS(NAME, CODE) int NAME() CODE
#define FUNCTION_NAME_LIST(NAME, CODE) NAME,
FUNCTION_TABLE(DEFINE_FUNCTIONS)
int (*function_table)(void)[] = { FUNCTION_TABLE(FUNCTION_NAME_LIST) };
If you have a C99 complying compiler, the 5 preprocessor has variable length argument 4 lists. P99 has a preprocessor P99_FOR
that can do 3 "code unrolling" like the one 2 you want to achieve. To stay close to your 1 example
#define MYFUNC(DUMMY, FN, I) int FN(void) { return I; }
#define GENFUNCS(...) \
P99_FOR(, P99_NARG(__VA_ARGS__), P00_IGN, MYFUNC, __VA_ARGS__) \
int (*function_table)(void)[] = { __VA_ARGS__ }
GENFUNCS(toto, hui, gogo);
would expand to the following (untested)
int toto(void) { return 0; }
int hui(void) { return 1; }
int gogo(void) { return 2; }
int (*function_table)(void)[] = { toto, hui, gogo };
This is sort of abuse of CPP but a common 5 type of abuse. I handle situations like 4 this by defining dummy macros
#define FUNCTIONS \
foo(a,b,c,d) \
foo(a,b,c,d) \
foo(a,b,c,d)
now,
#define foo(a,b,c,d) \
a+b ;
FUNCTIONS
#undef foo
later, when 3 you want something different done with the 2 same list
#define foo(a,b,c,d) \
a: c+d ;
FUNCTIONS
#undef foo
It's a bit ugly and cumbersome, but 1 it works.
There's this thing called X Macro which is used 5 as:
a technique for reliable maintenance 4 of parallel lists, of code or data, whose 3 corresponding items must appear in the same 2 order
This is how it works:
#include <stdio.h>
//you create macro that contains your values and place them in (yet) not defined macro
#define COLORS\
X(red, 91)\
X(green, 92)\
X(blue, 94)\
//you can name that macro however you like but conventional way is just an "X"
//and then you will be able to define a format for your values in that macro
#define X(name, value) name = value,
typedef enum { COLORS } Color;
#undef X //so you redefine it below
int main(void)
{
#define X(name, value) printf("%d, ", name);
COLORS
#undef X
return 0;
}
Solution for your 1 problem would be:
#define FUNCTIONS \
F(f1, code1)\
F(f2, code2)\
F(f3, code3)
#define F(name, code) int name(void){code}
FUNCTIONS
#undef F
#define F(name, code) &name,
int (*function_table[])(void) = { FUNCTIONS };
#undef F
Boost is a C++ library, but it's Preprocessor 4 module should still be good for use in C. It 3 offers some surprisingly advanced data types 2 and functionality for use in the preprocessor. You 1 could check it out.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.