Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I generate a list via the C preprocessor (cpp)?

I would like to do something like the following:

F_BEGIN

F(f1) {some code}
F(f2) {some code}
...
F(fn) {some code}

F_END

and have it generate the following

int f1() {some code}
int f2() {some code}
...
int fn() {some code}

int (*function_table)(void)[] = { f1, f2, ..., fn };

The functions themselves are easy. What I can't seem to do is to keep track of all of the names until the end for the function_table.

I looked at this question and this question but I couldn't get anything to work for me. Any ideas?

like image 901
No One in Particular Avatar asked Feb 05 '11 00:02

No One in Particular


People also ask

How do you use #define C++?

Remarks. The #define directive causes the compiler to substitute token-string for each occurrence of identifier in the source file. The identifier is replaced only when it forms a token. That is, identifier is not replaced if it appears in a comment, in a string, or as part of a longer identifier.

What is preprocessor directive in C++?

The preprocessors are the directives, which give instructions to the compiler to preprocess the information before actual compilation starts. All preprocessor directives begin with #, and only white-space characters may appear before a preprocessor directive on a line.

What is C preprocessor explain with example?

The C preprocessor is a macro preprocessor (allows you to define macros) that transforms your program before it is compiled. These transformations can be the inclusion of header files, macro expansions, etc. All preprocessing directives begin with a # symbol. For example, #define PI 3.14.


2 Answers

The normal way of doing this with the preprocessor is to define all the functions in a macro that takes another macro as an argument, and then use other macros to extract what you 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) };
like image 155
Chris Dodd Avatar answered Oct 21 '22 14:10

Chris Dodd


If you have a C99 complying compiler, the preprocessor has variable length argument lists. P99 has a preprocessor P99_FOR that can do "code unrolling" like the one you want to achieve. To stay close to your 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 };
like image 33
Jens Gustedt Avatar answered Oct 21 '22 14:10

Jens Gustedt