如何优雅地构造迭代C中数组的长参数列表

时间:2014-09-16 11:59:27

标签: c function arguments call construction

我有一个带有变量参数的C函数,我需要用很长的参数列表来调用它,其中参数都遍历数组的元素。例如:

myFunction( A[0], B[0], A[1], B[1], A[2], B[2], A[3], B[3], ..... A[N], B[N] );

其中N通常为100-200。

我宁愿不必在每次让N更大的时候手动构建这个调用,并且开始思考,有没有一种优雅的方法来做到这一点?

我尝试过类似的事情:

i=0;
myFunction( A[i], B[i++], A[i], B[i++], A[i], B[i++], A[i], B[i++], ..... A[i], B[++] );

但当然失败了。然而,最重要的是,只要我将N做大,我就可以一遍又一遍地复制相同的行,而不必确保每个数组索引都是正确的,这是非常繁琐的。

更改myFunction()不是一个选项。

我希望C有一种方法可以动态构建函数调用,例如:

for( i = 0 ; i <= N ; i++ )
{
    CONSTRUCT_CALL( myFunction, A[i], B[i] );
}

这正是我想要的,但当然这不是一种选择。

有什么可能更容易或更优雅吗?

非常感谢。

2 个答案:

答案 0 :(得分:2)

没有标准的C方法(在运行时合成可变参数调用)。但...

  • 您可以使用旨在处理此类问题的libffi(所以我推荐它)
  • 您可以考虑GCC特定Builtins for Constructing Calls
  • 你可以对arity有一些固定的限制(例如500)并且有一些C文件生成了一些(shell,awk,Python,...)脚本在500上执行switch案件,每个人都有一个。
  • 您可以考虑在运行时中生成一些C代码到_gen123.c,将其编译成可动态加载的插件(例如在Linux上分配一些gcc -shared -fPIC -Wall -O _gen123.c -o _gen123.so命令),然后加载插件(在Linux或Posix上使用dlopen(3)
  • 您可以考虑一些just-in-time compilation库(例如libjitllvm,GNU lightningasmjit,...)

当然,在一次通话中避免多个i++。避免使用undefined behavior,因为bad things可能会发生。

答案 1 :(得分:0)

你的设计中有一些非常糟糕的东西。

重写你的myFunction所以它需要两个数组(A和B),然后使用数量的索引。

调用这样一个函数的简短例子:

int A[100];
int B[100];
int c = myFunction(A, B, 100);

myFunction的可能实现:

int myFunction(int* A, int* B, int count)
{
    int result = 0;
    for(int j = 0; j < i; j++)
        result += A[j] + B[j]*2;

    return result;
}