Reputation: 1265
I want to forward args of variadic function, I have already find the some topic.
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
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.
Why the int 1 goes to another number but 2.3 still good.
How can I modify my code to implement the forward?
Thanks for your time.
Upvotes: 1
Views: 215
Reputation: 126140
fun1
needs a list of arguments to match its format, but when call it from fun2
you give it a va_list
. To call it that way you need to rewrite it to take a va_list
rather than a ...
:
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 ...
:
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. With this, it will warn you if the arguments passed to fun1
don't match the format string.
Upvotes: 4
Reputation: 1265
As suggtested by StoryTeller - Unslander Monica and Chris Dodd, My finial code looks like follows.
// 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;
}
Upvotes: 0