Functions with variable number of arguments

In C/C++, functions can be written to take variable no. of arguments. Examples are printf, sprintf, snprintf etc. The prototype of printf functions looks like int printf(const char *format, …). These functions internally use macros such as va_start, va_arg, va_end etc to get the passed parameters. But, I have observed that for every function like printf, there is another similarly defined function which takes va_list instead of … . For example, vprintf is similar to printf and has int vprintf(const char *format, va_list ap) prototype. In the same way, vsprintf and vsnprintf are also defined. Till now, I did not know the reason and used to think of it as an unnecessary wrapper.

For example, if a wrapper called myprintf needs to be written over printf

int myprintf(const char* format, …){

va_list ap;

va_start(ap,format);

???????

va_end(ap);

}

In the above code, I can not put ‘printf’ in place of ??????. Because printf is expecting variable arguments (like i, j , l) and not va_list dataype. So, in place of ??????, I should call vprintf which takes va_list.

So, I observed that it is a good practice to write 2 functions in case of variable number of arguments. One which takes variable no. of arguments as … and the other one taking va_list. An example is given below.

void vfunction (char * format, va_list ap){

/*This function does the actual work*/

}

void function(char* format, …){

/*This function just redirects to vfunction which does the work */

va_list ap;

va_start(ap,format);

vfunction(format, ap);

va_end(ap);

}

About these ads

3 Comments

  1. aji said,

    June 14, 2008 at 6:01 pm

    Quickly (my english is painfull)

    “Till now, I did not know the reason and used to think of it as an unnecessary wrapper.”
    is not, why ?

    In most of case (ex. libraries) a function with ‘…’ *is* a wrapper of a va_list,
    we can’t give a ‘…’ to an another function as is.
    Ex. void func (int foo, ….) { func2 (foo + 1, …. /* err! */); }

    So, now for my personal use I need any operation with a *printf, I do:
    int my_printf(const char *format, ….) {
    va_list args;
    int ret;

    va_start(args, format);
    /* any op. */
    ret = vprintf(format, args);
    va_end(args);

    return ret;
    }

    voilĂ .

  2. aji said,

    June 14, 2008 at 6:11 pm

    I’m sorry, i will drink my coffee now, i will read your post…
    An will see that i wrote what you wrote :/

  3. JAI said,

    October 17, 2011 at 3:48 pm

    i am not replying i jst want to know how to implement those

    va_list, va_arg, va_start, va_end if we want to create a function prototype which takes variable no of arguments such sa printf

    prototype of printf();

    int printf(const char*,…);


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: