0

I was looking for a way to pass an indefinite number of arguments to a function when I came across the way to do this using va_list, va_start and va_end of stdarg.h as illustrated in the program given here.

But couldn't find anywhere a way to access the indefinite number of arguments passed to function in a random fashion.

The way using va_list from stdarg.h header file is accessing the arguments sequentially. Once one argument is read there is no going back.

Is there a way to randomly access these arguments?

EDIT: I was advised to post the code instead of a link to the page containing it. So here it is:

#include <stdarg.h>
#include <stdio.h>

/* this function will take the number of values to average
followed by all of the numbers to average */
double average ( int num, ... )
{
    va_list arguments;                     
    double sum = 0;

    /* Initializing arguments to store all values after num */
    va_start ( arguments, num );           

    for ( int x = 0; x < num; x++ )        
    {
        sum += va_arg ( arguments, double ); 
    }
    va_end ( arguments );                  // Cleans up the list

    return sum / num;                      
}

int main()
{

    printf( "%f\n", average ( 3, 12.2, 22.3, 4.5 ) );
    /* here it computes the average of the 5 values 3.3, 2.2, 1.1, 5.5 and 3.3
    printf( "%f\n", average ( 5, 3.3, 2.2, 1.1, 5.5, 3.3 ) );
}
J...S
  • 5,079
  • 1
  • 20
  • 35
  • 2
    Put each one in an array? – Weather Vane Oct 28 '16 at 13:43
  • @WeatherVane i was thinking the same, just do a function who read thoses argument inside your va_list and save them in an array? It's possibly not what you want to do, but then add some precisions. – N.K Oct 28 '16 at 13:45
  • 1
    You'd still need to know the types, and the number of arguments (printf does this by walking the format string) BTW: there is also a hard limit on the number of arguments that a function can take. – joop Oct 28 '16 at 13:46
  • you can accept many think with stdarg. int, pointer, not the same size not the same type. This is why printf use a format string to know what she must do with va_list. I don't know alternative to [stdarg](https://linux.die.net/man/3/stdarg) in C – Stargateur Oct 28 '16 at 13:47
  • Post your code here. – chux - Reinstate Monica Oct 28 '16 at 14:43
  • @chux I have posted the code. – J...S Oct 28 '16 at 15:07

1 Answers1

1

There is no portable way to do that.

Suppose your function is called with three arguments, an int, a double, and a long double. They might all have different sizes.

The va_arg mechanism deliberately hides the underlying layout of the variable parameters, because it can vary from one implementation to another.

But let's assume a typical implementation might pass arguments on the stack, one after the other. Your function would have no way of knowing where in memory the third long double argument is without knowing the sizes of the first two arguments. And the amount of space taken up by each argument might not match the size of that argument; for example it might be more convenient to allocate 64 bits for a 32-bit argument.

<stdarg.h> deliberately provides a fairly minimal interface for accessing variable arguments. It only lets you access them in order, and only if you know the type of each argument.

If you want to do something similar, you could write a function that takes a pointer to the initial element of an array of pointers, each if which points to some data structure that can hold any of several types (perhaps something like a tagged union). But then the caller has to set up that structure before calling the function.

Fortunately that's not much a problem in practice. I can't think of any particular reason you'd need to access arguments randomly.

If you want to have an arbitrary number of arguments that are all of the same type, well, that's what arrays are for.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 1
    And if _were_ to try "going behind `stdarg`s back", be aware that on 64-bit platforms, _some_ of the arguments are passed in registers and the rest on the stack ([see this question and answers](http://stackoverflow.com/q/40216160/2096401)). – TripeHound Oct 28 '16 at 16:28