I am programming in C against a third party library (in HP/Mercury Loadrunner) that allows a varargs-style variable size argument list for one of it\'s functions. I want to
There are two way to pass a variable number of arguments: to a function that accepts "..." or to a function that accepts va_list.
You can not dynamically define the number of arguments for the "..." interface, but you should be able to do so for the va_list one. Google for va_start, va_end, and va_list.
Note: the code is already compiler-dependent (though perhaps not processor-dependent), because the invocation of web_submit_data
assumes there that the argument subexpressions in a procedure call are evaluated from left-to-right order, but the C language leaves the order of argument evaluation unspecified.
See for reference: http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_value
So perhaps the non-portable solution is not going to make things significantly worse for you.
Write it once with the preprocessor and never look back.
#define WEB_SUBMIT_BUFFER(name, val) \
do { \
const int size = 129; \
int i = 0; \
int j = 11; \
web_submit_data(&(name)[i++ * size], \
&(name)[i++ * size], \
/* etc ad nauseum */ \
} while (0)
Or if the number of arguments is fixed for each specific call, write a script to generate preprocessor defines to hide how heinous that call is.
#define WEB_SUBMIT_BUFFER_32(name, val) \
do { \
const int size = 129; \
int i = 0; \
int j = 11; \
web_submit_data(&(name)[i++ * size], \
&(name)[i++ * size], \
/* 32 times */ \
} while (0)
#define WEB_SUBMIT_BUFFER_33(name, val) ...
#define WEB_SUBMIT_BUFFER_34(name, val) /* etc */
Note that the code sample you posted has undefined behavior - the commas that separate function parameters are not sequence points (those commas are not the comma operator), so modifying i
and or j
multiple times in the function call argument list results in undefined behavior.
This is not to mention that the evaluation order of function call arguments is not specified by the standard - so even if you did the modification of i
and j
using functions to evaluate the arguments (function calls themselves are sequence points), you would be pretty much passing the pointers in an indeterminate order.
Also, I don't see how web_submit_data()
knows how many arguments it's been passed - I don't see a count or a definitive sentinel argument at the end. But I guess your example may be just that - an example that might not have complete, accurate details. On the other hand, it's web_submit_data()
's problem anyway, right?