Переменный список аргументов: использовать va_list или адрес формального параметра?

Приведенный ниже код содержит 2 функции, каждая из которых вычисляет сумму предоставленного списка целочисленных значений:

#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 использования va_list подход, sum_2 использует адрес предоставленного number_of_values переменная, относительно которой он находит другие значения и складывает их.

Так в чем же разница между этими двумя подходами? Какой использовать? Второй выглядит короче, так что нужно было определить va_list, va_start, va_art а также va_end?

2

Решение

Вторая версия непереносима, что является веским аргументом в пользу использования первой версии.

Вторая версия будет работать только в том случае, если на вашей платформе аргументы функции размещены в стеке определенным образом. Использование varargs отвлекает это, что делает первую версию переносимой.

3

Другие решения

Второй подход делает предположения о том, как аргументы передаются в функцию. Нет требования, чтобы эти предположения были выполнены. Вот почему va_list и его друзья существуют: поставщик библиотеки знает, как передаются аргументы, и может правильно реализовать код.

2

По вопросам рекламы [email protected]