Link to home
Start Free TrialLog in
Avatar of Farzad_6e
Farzad_6e

asked on

Function with unlimited arguments???

Hi all,
I want to know that how is it possible to have a function that can be called with a variable number of argument of a specific type,
for example:
f1(12,13,24);
f1(12,32,43,43,34);
and there is no idea about number of argument so overloading seems to be useless

thanx in advance...
ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of AlexFM
AlexFM

UNIX-compatible version of the same function:

int average( va_alist )
va_dcl
{
   int i, count, sum;
   va_list marker;

   va_start( marker );            /* Initialize variable arguments. */
   for( sum = count = 0; (i = va_arg( marker, int)) != -1; count++ )
      sum += i;
   va_end( marker );              /* Reset variable arguments.      */
   return( sum ? (sum / count) : 0 );
}
>> Writing of function with variable number of arguments is not safe and requires some
>> agreements between caller and function. For example, first argument may be number
>> of arguments of the function. Incorrect call effectively crashes a program, as we can
>> see using, for example, scanf.
Agreed!   VA (Variable argument) functions are one of the leading causes of bugs in C programs.  C++ and the STL were developed in part to prevent these bugs by eliminating the need for VA functions.   So I really think you should reconsider using VA functions.  C++ provides many alternative techniques that elminate the need for resorting to VA.  We might be able to sugest some if you coudl explain what it is you are trying to do.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
One solution might be to use an array and count. like this
func(int CountofElements, int *ArgArray);
It requires that you trust the caller only slightly less than the VA situation.
The reason why VA is not safe is that it is perfectly possible to do mistakes, referring to my two methods of providing VA arguments above.

If you have a 'stop value' you can simply call the function without having the stop value at the end.

concat("hello ", "there");

will crash.


The other method you can give fewer or more arguments than your info argument indicate. If the poly is called like this:


poly(15, 0.5, 2, 3, 7);

it will crash, similarly:

poly(3, 0.5, 2, 3, 7, 11, 19);

This will compute f(x) with x = 0.5 for
2 * x*x*x + 3*x*x + 7*x + 11. The argument 19 is not read or used.

A similar situation occur in method 1 above if you provide arguments after the stop-value:

concat("hello, ", 0, "how are you?");

will only return a string containing "hello, ", the "how are you?" part is never read or used.

Avoiding va args eliminate these problems. However, this elmination isn't really very true. The problem is that the only other way to provide a variable number of arguments to one single function call is to provide an array and using that array you can lie about the size of it, it is also more troublesome to set up an array so it doesn't really solve it.

This leaves you to using a set of functions to provide the functionality and in this C++ provide a very good mechanism as shown by iostream. Creating an object and then "stuff" values into that object can

1. Preserve type of the value.
2. Preserve the number of values.
3. is safe.

Then providing that object as argument to your function will the process the values as you should.

For example a concat using this method is easy to write using stringstream:

stringstream ss;
ss << "string one";
ss << "string two";
...

ss.c_str() is now the concatenated string.

Similar method for printf is found in the boost formatter library where you create a format class with format and then give it values in a similar manner.

Using overloads you also get it so that you can remember the type of the value provided etc and you can use type specific overloads for using the value.

However, if you don't want to use this technique, then I doubt that using arrays is any safer than va_args, giving an array and saying it has 10 elements is just as bad as calling a VA function with the wrong setup. I would think it is also just as easy to make both those mistakes because they are fundamentally the same error - mismatch between how the function call should be and how it is.

Alf
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Split Points between AlexFM & Salte

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer