如何优雅地构建在C中遍历数组的长参数列表



我有一个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] );
}

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

有什么可能更简单或更优雅的吗?

非常感谢。

没有标准的C方法可以做到这一点(在运行时合成可变调用)。但是

  • 你可以使用libffi来处理这些问题(所以我推荐它)
  • 您可以考虑构造调用的GCC特定内置
  • 您可以对arity有一些固定的限制(例如500),并使用一些(shell、awk、Python…)脚本生成一些C文件,对500个案例执行switch,每个arity一个
  • 您可以考虑在运行时将一些C代码生成到_gen123.c中,将其编译为可动态加载的插件(例如,在Linux上派生一些gcc -shared -fPIC -Wall -O _gen123.c -o _gen123.so命令),然后加载该插件(在Linux或Posix上使用dlopen(3))
  • 您可能会考虑一些即时编译库(例如libjit、llvm、GNU闪电、asmjit…)

当然,在一个调用中要避免多个i++。避免不明确的行为,因为坏事可能发生。

您的设计中有一些非常糟糕的地方。

重写您的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;
}

相关内容

  • 没有找到相关文章

最新更新