-1

I have a C function that takes variable arguments, and I need to call it with a very long list of arguments, where the arguments all step through the elements of an array. Example:

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

where N is typically 100-200.

I would prefer not having to construct this call manually every time I make N bigger, and got to thinking, is there an elegant way to do this?

I tried something like:

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

but of course that fails. What is preferred about it, however, is anytime I make N larger, I can simply copy the same line over and over, instead of having to ensure each array index is correct, which is quite tedious.

Changing myFunction() is not an option.

I wish C had a way to construct function calls on the fly, like:

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

which would be exactly what I want, but of course that's not an option.

Is there anything that might be easier or more elegant?

Thank you very much.

2 Answers2

2

There is no standard C way of doing that (synthesizing a variadic call at runtime). But...

  • you can use libffi which is designed to handle such issues (so I recommend it)
  • you could consider GCC specific Builtins for Constructing Calls
  • you could have some fixed limit on the arity (e.g. 500) and have some C file generated with some (shell, awk, Python, ...) script doing a switch on the 500 cases, one for each arity.
  • you might consider generating some C code at runtime into _gen123.c, compile it into a dynamically loadable plugin (e.g. forking some gcc -shared -fPIC -Wall -O _gen123.c -o _gen123.so command on Linux), then loading that plugin (with dlopen(3) on Linux or Posix)
  • you might consider some just-in-time compilation library (e.g. libjit, llvm, GNU lightning, asmjit, ...)

Of course, avoid several i++ in a single call. Avoid undefined behavior, since bad things could happen.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
0

There is something very bad in your design.

Rewrite your myFunction so it takes two arrays (A and B) and then takes numer of indices to use.

A short example of calling such a function:

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

A possible implementation of 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;
}
Michał Walenciak
  • 4,257
  • 4
  • 33
  • 61
  • But he said: *Changing `myFunction()` is not an option* – Basile Starynkevitch Sep 16 '14 at 12:19
  • 1
    Yeah, havn't noticed it. Anyway there is still no other option for doing it right ;) Maybe a good solution here would be to prepare `myFunction2` doing the same stuff in nicer way? – Michał Walenciak Sep 16 '14 at 12:22
  • There is no "nicer" (and standardized) way available unless there is a variant of the function which takes a `va_list`. It's very sad that there are people actually producing function interfaces like this. – Daniel Kamil Kozar Sep 16 '14 at 13:10