You have already found an answer to your problem. I think using the array variant of the function is the way to go. (The comment on the dsp_addv
function is telling.)
However, this does not answer my question...
Depending on the nature of the variadic function, you can write a wrapper function that calls the variadic function. This will not work in all cases, but for some frequent cases. (Variadic functions themselves are rather restricted in their use. Somewhere, I've read a claim that they exist only to implement printf
.)
Iteration
Something is done to each variadic argument: It is printed, for example, or it is added to a list. In that case you can just call the function for each argument:
#include <stdio.h>
#include <stdarg.h>
void varg_print(const char *str, ...)
{
va_list va;
va_start(va, str);
while (str) {
puts(str);
str = va_arg(va, const char *);
}
va_end(va);
}
void arr_print(const char **str)
{
while (*str) varg_print(*str++, NULL);
}
int main()
{
const char *fruit[]) = {"apple", "pear", "banana", NULL};
arr_print(fruit);
return 0;
}
Reduction
All arguments are reduced to a single value, for example their sum or their max values. Here you can treat sub-arrays until you get what you want. The example below forwards an array to a summation function at most four elements at a time and overwrites the lower regions of the array with the result until there is only a single value left.
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
double varg_sum(int n, ...)
{
double s = 0.0;
va_list va;
va_start(va, n);
while (n--) s += va_arg(va, double);
va_end(va);
return s;
}
double arr_sum(int n, double *x)
{
double r[n];
if (n <= 0) return 0.0;
memcpy(r, x, n * sizeof(*x));
while (n > 1) {
double *p = r;
int m = 0;
while (n) {
switch (n) {
case 1: r[m++] = varg_sum(1, p[0]);
n -= 1;
p += 1;
break;
case 2: r[m++] = varg_sum(2, p[0], p[1]);
n -= 2;
p += 2;
break;
case 3: r[m++] = varg_sum(3, p[0], p[1], p[2]);
n -= 3;
p += 3;
break;
default: r[m++] = varg_sum(4, p[0], p[1], p[2], p[3]);
n -= 4;
p += 4;
break;
}
}
n = m;
}
return r[0];
}
int main()
{
double x[100];
int i;
for (i = 0; i < 100; i++) x[i] = i + 1.0;
printf("%g\n", arr_sum(100, x));
return 0;
}
The code makes a copy of the array so that the original array isn't destroyed. You can increase the chunk size in order to treat bigger arrays more effectively, but variadic functions aren't designed for long variadic lists anyway, so four seems okay.