7

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.

4

4 回答 4

4

如果您不关心数组中函数的顺序,并且愿意使用 GCC 扩展,那么您可以使用一大堆初始化器(构造器)函数来实现您想要的。这显然不是理想的,因为定义了大量额外的函数,但它肯定是您可以考虑的一种方法。它在运行时构造数组。

定义函数append以将单个函数附加到数组(如果需要,重新分配)。然后,代码基本上是

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

ARRAYFUNC(func1) {
    ...
}

ARRAYFUNC(func2) {
    ...
}
于 2013-09-13T21:13:49.570 回答
3

您可以为此使用 C 预处理器 ( X-Macros ):

#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;
}

输出是:

$ gcc test.c && ./a.out
5
6
0
于 2013-09-13T20:47:30.497 回答
2

我不认为有任何其他方式可以做想做的事。

你写的

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

已经做了最好的。

也许你可以用前缀 0000 到 1000 来命名你的函数,这样你就可以确保每个函数都在你的函数指针数组中的正确位置。

此外,如果您真的有 1000 个不同的函数,它们肯定是共同的,可以引导您将它们排序到多个数组中,减少编号工作,并且不易出错。

于 2013-09-13T19:38:56.427 回答
2

我用来解决这种情况的方法(当然,只有在我无法避免的情况下)是使用预处理。不是 C 预处理器中可用的那个,它没有以合理的语法提供所需的功能,而是一个非常强大的功能,例如m4.

使用m4,您的代码可能如下所示:

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();

你只需要为and提供正确的m4定义,你就拥有了你需要的功能。functionArrayMember()buildFunctionArray()

于 2013-09-13T19:42:41.160 回答