如何正确va_end?

Posted

技术标签:

【中文标题】如何正确va_end?【英文标题】:How to properly va_end? 【发布时间】:2016-05-26 07:25:39 【问题描述】:
#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 是否会被正确结束,即使它没有被引用调用?

【问题讨论】:

【参考方案1】:

变量参数列表:

你不应该在以va_list 作为参数的函数中使用va_end

来自va_arg 的 (Linux) 手册页:

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

(强调我的)

在具有va_list 参数的函数中,按值获取va_list(就像vprintf 之类的C 库函数,...也一样)。

示例:

#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 可能malloc 一些空间和va_end 可能free @M.M:除了,mallocfree 可以(并且经常)在不同的函数中调用。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

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

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

【讨论】:

以上是关于如何正确va_end?的主要内容,如果未能解决你的问题,请参考以下文章

va_start和va_end的使用及原理

是否需要在具有多个“return”语句的可变参数函数中的每个“return”语句之前调用“va_end()”?

va_list/va_start/va_arg/va_end深入分析

va_start和va_end vsnprintf和snprintf

[C语言] va_start和va_end详解

va_list va_start va_arg va_end 使用说明