Variable argument list: use va_list or address of formal parameter?

686 views Asked by At

The code below contains 2 functions both of which calculate a sum of supplied list of integer values:

#include <iostream>
#include <stdarg.h>

using namespace std;

int sum_1 ( int number_of_values, ... )
{
    va_list arguments;
    va_start ( arguments, number_of_values );
    int sum = 0;
    for ( int i = 0; i < number_of_values; i++ )
    {
        sum += va_arg ( arguments, int );
    }
    va_end ( arguments );

    return sum;
}

int sum_2 ( int number_of_values ...)
{
    int sum = 0;
    for ( int i = 0; i < number_of_values; i++ )
        sum += *( &number_of_values + i + 1 );
    return sum;
}


int main()
{
    cout << sum_1(3, 1, 2, 3) << endl; //prints 6
    cout << sum_2(3, 1, 2, 3) << endl; //prints 6
}

sum_1 uses va_list approach, sum_2 uses address of supplied number_of_values variable relatively to which it finds other values and adds them up.

So what's the difference between these 2 approaches? Which one to use? Second one looks shorter, so what was care to define va_list, va_start, va_art and va_end?

2

There are 2 answers

4
NPE On BEST ANSWER

The second version is non-portable, which is a strong argument for using the first version.

The second version would only work if on your platform the function's arguments are laid out on the stack in a particular fashion. The use of varargs abstracts that away, which is what makes the first version portable.

0
Pete Becker On

The second approach makes assumptions about how arguments are passed to the function. There is no requirement that those assumptions be met. That's why va_list and its buddies exist: the library vendor knows how arguments are passed, and can implement the code correctly.