Frage

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?

War es hilfreich?

Lösung

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.

Andere Tipps

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top