【问题标题】:converting va_list to variable argument? [duplicate]将 va_list 转换为变量参数? [复制]
【发布时间】:2014-09-15 14:49:47
【问题描述】:

我有一个函数log_message 它接受可变参数。

log_message(int level, char *fmt, ...)

现在在调用这个(log_message) 函数之前,我必须添加新函数(_log_message),新函数将调用log_message

_log_message(int level, char *fmt, ...)

新功能也是一样的。当_log_message 调用log_message 时,它会将变量输入转换为va_list。现在我有va_list,我不想改变原来的,有什么办法可以改回可变输入,所以我可以调用原来的(log_message)。

【问题讨论】:

    标签: c variadic-functions


    【解决方案1】:

    不,没有办法将va_list 转回参数列表。

    通常的方法是定义一个以va_list 作为参数的基本函数。例如标准C库定义printfvprintf;第一个是可变参数函数,第二个具有完全相同的功能,但取而代之的是 va_list。同样,它定义了fprintfvfprintf。用vfprintf 定义printfvprintffprintf 很简单:

    int fprintf(FILE* stream, const char* format, ...) {
      va_list ap;
      va_start(ap, format);
      int n = vfprintf(stream, format, ap);
      va_end(ap);
      return n;
    }
    
    int vprintf(const char* format, va_list ap) {
      return vfprintf(stdout, format, ap);
    }
    
    int printf(const char* format, ...) {
      va_list ap;
      va_start(ap, format);
      int n = vprintf(format, ap);
      va_end(ap);
      return n;
    }
    

    (同样适用于各种exec* 函数,它们有va_listvarargs 两种。)

    我建议你采用类似的策略。

    【讨论】:

    • 为什么不可能?这看起来像一个幼稚的问题,但我仍然想知道。
    • 这是不可能的,因为没有处理它的例程或语法。 c_decl 要求调用者将项目推入堆栈。如果是可变数,它怎么知道要推入多少?最后,调用者负责拆栈——同样,如果它不知道有多少,它怎么知道有多少要拆?
    • @Merom 仅仅是因为标准没有定义可靠的方法来做到这一点。调用期间的堆栈看起来完全不同。在通常的平台下,... 是在堆栈上连续传递的,va_list 是一种指向这样连续的... 参数的指针。而且他们根本没有提供将它们放回堆栈的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-30
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 2019-05-08
    • 2019-09-06
    相关资源
    最近更新 更多