Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wrap a function with variable length arguments?

I am looking to do this in C/C++.

I came across Variable Length Arguments but this suggests a solution with Python & C using libffi.

Now, if I want to wrap printf function with myprintf

What I do is like below:

void myprintf(char* fmt, ...) {     va_list args;     va_start(args,fmt);     printf(fmt,args);     va_end(args); }  int _tmain(int argc, _TCHAR* argv[]) {     int a = 9;     int b = 10;     char v = 'C';     myprintf("This is a number: %d and \nthis is a character: %c and \n another number: %d\n",a, v, b);     return 0; } 

But the results are not as expected!

This is a number: 1244780 and this is a character: h and another number: 29953463 

Any point where did I miss??

like image 585
prakash Avatar asked Sep 03 '08 10:09

prakash


People also ask

How do you use variable length arguments?

A variable-length argument is a feature that allows a function to receive any number of arguments. There are situations where a function handles a variable number of arguments according to requirements, such as: Sum of given numbers. Minimum of given numbers and many more.

Which of the following function definitions allows the function to accept variable length arguments?

The special syntax **kwargs in function definitions in python is used to pass a keyworded, variable-length argument list. We use the name kwargs with the double star. The reason is that the double star allows us to pass through keyword arguments (and any number of them).

How Python handles the variable length arguments explain with example?

You may need to process a function for more arguments than you specified while defining the function. These arguments are called variable-length arguments and are not named in the function definition, unlike required and default arguments.


2 Answers

the problem is that you cannot use 'printf' with va_args. You must use vprintf if you are using variable argument lists. vprint, vsprintf, vfprintf, etc. (there are also 'safe' versions in Microsoft's C runtime that will prevent buffer overruns, etc.)

You sample works as follows:

void myprintf(char* fmt, ...) {     va_list args;     va_start(args,fmt);     vprintf(fmt,args);     va_end(args); }  int _tmain(int argc, _TCHAR* argv[]) {     int a = 9;     int b = 10;     char v = 'C';      myprintf("This is a number: %d and \nthis is a character: %c and \n another number: %d\n",a, v, b);     return 0; } 
like image 127
Mark Avatar answered Sep 23 '22 14:09

Mark


In C++11 this is one possible solution using Variadic templates:

template<typename... Args> void myprintf(const char* fmt, Args... args ) {     std::printf( fmt, args... ) ; } 

EDIT

As @rubenvb points out there are trade-offs to consider, for example you will be generating code for each instance which will lead to code bloat.

like image 27
Shafik Yaghmour Avatar answered Sep 20 '22 14:09

Shafik Yaghmour