Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

defining an array of C functions

I've got a bunch of C functions which get assigned to an array of function pointers, along the lines of this:

typedef int (*func)(int);

int SomeLongName1(int a) {         
  // ...
}                      

// ...

int SomeLongName1000(int a) {         
  // ...
}                      

func f[] = { SomeLongName1, ... , SomeLongName1000 };

This is a lot of work to create and is prone to errors. For instance, there could be a typo in the function name such that a valid function is still named, but the wrong one. Or, if a new function is added at the end one could forget to go in and explicitly add it to the list of function pointers as well.

In order to avoid having to explicitly declare the array of function pointers I have tried various tricks such as macros, which make the code hard to understand and require knowing how the macro works, and I am generally unsatisfied with them.

What I would like to do is something like this:

typedef int (*func)(int);

func f[] = {             
  int SomeLongName1(int a) {         
    // ...
  }                      
  // ...                   
  int SomeLongName1000(int a) {         
    // ...
  }                      
};                       

This way, the array would be automatically created, and if there was some way to put a null pointer at the end so I can determine how many function pointers there are that would be great as well.

However, the above isn't valid C and I'm coming up empty with any way of accomplishing this. If it is something compiler specific (e.g. a GCC extension) that would be ok.

All the functions are statically known at compile time, so I would like to avoid having to do any run-time initialization of the function pointer array - not that I have found a method to do it that way either.

This related question How to define an array of functions, seems to ask the same question, but does not carry it to its logical conclusion. Specifically, I don't want to have to re-type anything I have already typed so as to save time and avoid errors.

like image 800
Michael Avatar asked Sep 13 '13 19:09

Michael


People also ask

Can you have an array of functions C?

Array Functions in C is a type of data structure that holds multiple elements of the same data type. The size of an array is fixed and the elements are collected in a sequential manner. There can be different dimensions of arrays and C programming does not limit the number of dimensions in an Array.

How do you define an array in a function?

To pass an entire array to a function, only the name of the array is passed as an argument. result = calculateSum(num); However, notice the use of [] in the function definition. This informs the compiler that you are passing a one-dimensional array to the function.

Can I #define an array in C?

In the latest version of C, you can either declare an array by simply specifying the size at the time of the declaration or you can provide a user-specified size. The following syntax can be used to declare an array simply by specifying its size. // declare an array by specifying size in [].

What is an array definition in C?

Arrays in C. An array is a variable that can store multiple values. For example, if you want to store 100 integers, you can create an array for it.


4 Answers

If you don't care about the order of functions in the array, and are willing to use a GCC extension, then you can achieve what you want using a whole bunch of initializer (constructor) functions. This obviously isn't ideal because of the sheer number of extra functions defined, but it is certainly one approach you can consider. It constructs the array at runtime.

Define the function append to append a single function to an array (reallocating if needed). Then, the code is basically

#define ARRAYFUNC(name) int name(int); \
    void __attribute__((constructor)) __init_##name(void) { append(func); } \
    int name(int a)

ARRAYFUNC(func1) {
    ...
}

ARRAYFUNC(func2) {
    ...
}
like image 93
nneonneo Avatar answered Oct 16 '22 14:10

nneonneo


You could use the C preprocessor (X-Macros) for this:

#include <stdio.h>

// define a list of function names and bodies
#define FUNCS \
  FUNC(add, { return a+b; }) \
  FUNC(mul, { return a*b; }) \
  FUNC(div, { return a/b; })

// let the preprocessor make up the actual function implementations
#define FUNC(name, body) int name(int a, int b) body
FUNCS
#undef FUNC

typedef int (*func)(int, int);

// let the preprocessor populate the array of function pointers
func f[] = {
#define FUNC(name, body) name, 
FUNCS
#undef FUNC
};

// use it:
int main () {
    int a = 2, b = 3, i = 0;
    for (; i < sizeof(f)/sizeof(*f); i++) {
        printf("%d\n", f[i](a,b));
    }
    return 0;
}

The output is:

$ gcc test.c && ./a.out
5
6
0
like image 26
moooeeeep Avatar answered Oct 16 '22 16:10

moooeeeep


What I would use to solve such a situation (only if I can't avoid it, of course), is to use preprocessing. Not the one available from the C preprocessor, it does not provide the required functionality in a sensible syntax, but a really powerful one like m4.

With m4, your code could look like this:

define(`functionList', `, 0')
define(`functionArrayMember', `define(`functionList', `$1, 'FunctionList)$1')
define(`buildFunctionArray', `{ functionList }')

int functionArrayMember(SomeLongName1)(int a) {
    return a+1;
}
//...
int functionArrayMember(SomeLongName1000)(int a) {
    return a+1;
}

func f[] = buildFunctionArray();

You just need to provide the right m4 definition for functionArrayMember() and buildFunctionArray(), and you have the functionality you need.

like image 24
cmaster - reinstate monica Avatar answered Oct 16 '22 15:10

cmaster - reinstate monica


I do not think there is any other way of doing what want to do.

What you wrote

func f[] = { SomeLongName1, ... , SomeLongName1000 };

already does what is best.

Maybe you could name your functions with an prefix 0000 to 1000, so that you can be sure each function is in the right place in your functions pointer array.

Also, if you really have 1000 different functions, they are surely things in common that could lead you to sort them in several arrays, reducing the numbering effort, and that is less error prone.

like image 37
LudoZik Avatar answered Oct 16 '22 15:10

LudoZik