昨夜遅くに書きましたが、投稿しようとしたときにインターネット接続がダウンしました。ヨアヒムが本質的に同じ答えを書いているのがわかります。
制限内で、これは機能します:
#include <assert.h>
extern double function_invoker(void *func, int n, double *values);
double function_invoker(void *func, int n, double *values)
{
switch (n)
{
case 0:
return (*(double (*)(void))func)();
case 1:
return (*(double (*)(double))func)(values[0]);
case 2:
return (*(double (*)(double, double))func)(values[0], values[1]);
case 3:
return (*(double (*)(double, double, double))func)(values[0], values[1], values[2]);
default:
assert("Need more entries in the switch in function_invoker()" == 0);
return(0.0);
}
}
明らかな制限は、 に作成するエントリの数ですswitch
。大まかに類似したコードが 100 を超える引数になるのを見てきました。なぜそれが必要だと考えられたのかはわかりません。
このコードは、Mac OS X 10.8.2 の GCC 4.6.0 で警告なしにコンパイルされます。
$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -c x.c
$
しかしdouble (*)()
、代わりに を使用すると、次のvoid *
ようになります。
$ gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -c x.c
x.c:3:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
x.c:5:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
$