简体   繁体   English

如何正确va_end?

[英]How to properly va_end?

#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;
}

When taking va_list to another function, how should I pass it to that function? va_list带到另一个函数时,我应该如何将它传递给该函数? I know that va_end must be called when things are done with va_list I'm confused whether I should call it by reference or not. 我知道当使用va_list完成任务时必须调用va_end我很困惑我是否应该通过引用来调用它。 Will va_list be properly ended even though it is not called by reference? va_list会正确结束,即使它没有通过引用调用?

Variable argument lists: 变量参数列表:

You should never use va_end in a function taking the va_list as argument! 你不应该在以va_list为参数的函数中使用va_end

From the (Linux) man-page for va_arg : va_arg的(Linux)手册页:

Each invocation of va_start() must be matched by a corresponding invocation of va_end() in the same function . 每次调用va_start()都必须与同一函数中相应的va_end()调用相匹配。

(Emphasis mine) (强调我的)

In a function having a va_list argument, take the va_list by value (as C-library functions like vprintf , ... do, too). 在具有va_list参数的函数中,按值获取va_list (作为c-library函数,如vprintf ,...也可以)。

Example: 例:

#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);
}

Note: 注意:

In C++ you should avoid variable argument lists. 在C ++中,您应该避免使用变量参数列表。 Alternatives are std::array , std::vector , std::initializer_list and variadic templates. 替代方案是std::arraystd::vectorstd::initializer_list和variadic模板。

I prefer to call va_end in the same function in which I called va_start or va_copy, like any other resource allocation/deallocation pair. 我喜欢在与我调用va_start或va_copy相同的函数中调用va_end,就像任何其他资源分配/释放对一样。 That style is required by the standard, although some implementations are more tolerant. 标准需要这种风格,尽管有些实现更宽容。

Normally, va_lists are passed by value. 通常,va_lists按值传递。 They are small objects. 它们是小物件。

The macro function va_end is implemented as either void statement or resetting the va_list variable. 宏函数va_end实现为void语句或重置va_list变量。

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

Theoretically, you can call it anywhere, or even skip it. 从理论上讲,你可以在任何地方调用它,甚至可以跳过它。 However, to be a good programmer, we need to put it after the va_ functions 但是,要成为一名优秀的程序员,我们需要将其放在va_函数之后

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

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