如何正确va_end

How to properly va_end?

本文关键字:end va 何正确      更新时间:2023-10-16
#include <cstdarg>
using namespace std;
void do_something( va_list numbers, int count ) {
//                         ^
// Should I call this by reference here? I mean, va_list & numbers?
    //... stuff
    va_end( numbers );
}
void setList( int count, ... ) {
    va_list numbers;
    va_start( numbers, count );
    do_something( numbers, count );
}
int main() {
    setList( 2, 0, 1 );
    return 0;
}

va_list传递给另一个函数时,我应该如何将其传递给该函数?我知道当事情完成时必须调用va_end va_list我很困惑我是否应该通过引用来调用它。即使没有通过引用调用va_list,它也会正确结束吗?

变量参数列表:

您永远不应该在将va_list作为参数的函数中使用va_end

从 (Linux) 手册页va_arg

每次调用 va_start() 必须匹配相应的 在同一函数中调用 va_end()。

(强调我的)

在具有va_list参数的函数中,按值获取va_list(如 C 库函数,如 vprintf 、...也这样做)。

例:

#include <cstdarg>
#include <iostream>
void v_display_integers(int count, va_list ap) {
    while(0 < count--) {
        int i = va_arg(ap, int);
        std::cout << i << 'n';
    }
}
void display_integers(int count, ...) {
    va_list ap;
    va_start(ap, count);
    v_display_integers(count, ap);
    va_end(ap);
    // You might use 'va_start' and 'va_end' a second time, here.
    // See also 'va_copy'.
}
int main() {
    display_integers(3, 0, 1, 2);
}

注意:

在C++中,您应该避免使用变量参数列表。替代模板是std::arraystd::vectorstd::initializer_list和可变参数模板。

我更喜欢在调用va_start或va_copy的同一函数中调用va_end,就像任何其他资源分配/释放对一样。该样式是标准所要求的,尽管某些实现更宽容。

通常,va_lists是按值传递的。它们是小物体。

函数va_end实现为 void 语句或重置 va_list 变量。

http://research.microsoft.com/en-us/um/redmond/projects/invisible/include/stdarg.h.htm

从理论上讲,您可以在任何地方调用它,甚至可以跳过它。但是,要成为一名优秀的程序员,我们需要将其放在va_函数之后。