简体   繁体   English

可变参数列表:使用va_list还是形式参数的地址?

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

The code below contains 2 functions both of which calculate a sum of supplied list of integer values: 下面的代码包含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 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. sum_1使用va_list方法, sum_2使用所提供的number_of_values变量的地址,相对于该变量,它查找其他值并将其相加。

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 ? 第二个看起来较短,那么定义va_listva_startva_artva_end什么?

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. 使用varargs可以将其抽象化,这就是第一个版本可移植的原因。

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. 这就是va_list及其伙伴存在的原因:库供应商知道如何传递参数,并且可以正确实现代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM