简体   繁体   English

在 C 中转发可变参数 function

[英]forward args of variadic function in C

I want to forward args of variadic function, I have already find the some topic.我想转发可变参数 function 的参数,我已经找到了一些主题。

When I start to practice, I found a problem.当我开始练习时,我发现了一个问题。

#include <stdio.h>
#include <stdarg.h>
void fun1(const char *msg, ...) // try to forward printf
{
    va_list arg_list;
    va_start(arg_list, msg);
    vprintf(msg, arg_list);
    va_end(arg_list);
}

void fun2(const char *msg, ...) // try to forward fun1
{
    va_list arg_list;
    va_start(arg_list, msg);
    fun1(msg, arg_list);
    va_end(arg_list);
}

int main()
{
    fun1("this is int %d, float %f\n", 1, 2.3);
    fun2("this is int %d, float %f\n", 1, 2.3);
    return 0;
}

I compile code with gcc main.c and the output shown that我用gcc main.c和 output 编译代码表明

this is int 1, float 2.300000
this is int 6684168, float 2.300000

I can not understand why the fun2 not forward the args of fun1 correctly.我不明白为什么fun2不能正确转发fun1的参数。 Why the int 1 goes to another number but 2.3 still good.为什么 int 1 转到另一个数字但 2.3 仍然很好。 How can I modify my code to implement the forward?如何修改我的代码来实现转发?

Thanks for your time.谢谢你的时间。

fun1 needs a list of arguments to match its format, but when call it from fun2 you give it a va_list . fun1需要一个 arguments 的列表来匹配它的格式,但是当从fun2调用它时,你给它一个va_list To call it that way you need to rewrite it to take a va_list rather than a ... :要这样称呼它,您需要重写它以采用va_list而不是...

void fun1(const char *fmt, va_list args) {
    vfprintf(fmt, args);
}

If you're using gcc, you can avoid many problems of this nature by using -Wall and adding a declaration for your functions that take ... :如果你使用 gcc,你可以通过使用-Wall并为你的函数添加一个声明来避免许多这种性质的问题,这些声明采用...

extern void fun2(const char *fmt, ...) __attribute__((format(printf, 1, 2)));

This tells gcc that fun2 takes printf-style arguments starting from the second argument with the first argument as the format.这告诉 gcc fun2采用 printf 样式 arguments 从第二个参数开始,第一个参数作为格式。 With this, it will warn you if the arguments passed to fun1 don't match the format string.这样,如果传递给fun1的 arguments 与格式字符串不匹配,它会警告您。

As suggtested by StoryTeller - Unslander Monica and Chris Dodd, My finial code looks like follows.正如 StoryTeller - Unslander Monica 和 Chris Dodd 所建议的,我的最终代码如下所示。

// before modify
//   vprintf  <-- fun1  <-- fun2


//    after modify

//    vprintf  <-- vfun1 <--- fun1
//                         |- fun2
#include <stdio.h>
#include <stdarg.h>
void vfun1(const char *msg, va_list arg_list)
{
    printf("this is vfun1\n");
    vprintf(msg, arg_list);
}

void fun1(const char *msg, ...) // try to forward vprintf, but implemented by call vfun1
{
    printf("this is fun1\n");
    va_list arg_list;
    va_start(arg_list, msg);
    vfun1(msg, arg_list);
    va_end(arg_list);
}

void fun2(const char *msg, ...) // try to forward fun1, but implemented by call vfun1
{
    printf("this is fun2\n");
    va_list arg_list;
    va_start(arg_list, msg);
    vfun1(msg, arg_list);
    va_end(arg_list);
}

int main()
{
    printf("------------------------------------\n");
    fun1("this is int %d, float %f\n", 5, 2.3);
    
    printf("------------------------------------\n");
    fun2("this is int %d, float %f\n", 5, 2.3);
    return 0;
}

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

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