Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > passing var args as-is to a function

Reply
Thread Tools

passing var args as-is to a function

 
 
sinbad
Guest
Posts: n/a
 
      03-25-2013
i have a common function which takes variable parameters as an argument,
depending on the type (the first arg) i want to call the appropriate
function with rest of the param list, is there any way to do this or
any better approach. i'm trying to avoid the switch() statement
below.

void
common_func(int type, ...);

void
do_one(int x, int y);

void
do_two(char a, char b);

void
do_any();

void
common_func(int type, ...)
{
switch(type) {
case 1;
do_one(); /* pass 2,3 */
break;

case 2:
do_two(); /* pass 5,6 */
break;

default:
do_any();

}
return;
}

int main()
{
comon_func(1, ,2 ,3);
comon_func(2, ,5 ,6);
}
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      03-25-2013
On 03/25/2013 05:44 AM, sinbad wrote:
> i have a common function which takes variable parameters as an argument,
> depending on the type (the first arg) i want to call the appropriate
> function with rest of the param list, is there any way to do this or
> any better approach. i'm trying to avoid the switch() statement
> below.


It would help to know why you want to avoid the switch() statement.
Every alternative I can think of to the switch statement is just a
different way of implementing a switch (such as if(type==1) {} else
if(type==2) {} else {}). They don't save you any significant amount of
typing, and they won't significantly affect how fast the program will
actually execute. They may make it harder to understand your program,
because the basic logical structure of any function like this
corresponds directly to a switch statement, and using other structure to
achieve the same result would serve only to obscure that fact.

> void
> common_func(int type, ...);
>
> void
> do_one(int x, int y);
>
> void
> do_two(char a, char b);


The promoted type of char is 'int' (unless CHAR_MAX > INT_MAX, an
unlikely but possible situation, in which case the promoted type would
be unsigned int). Since the integer promotions are automatically
performed on the variable portion of the argument list, that makes this
a bad choice for an example. If these were the only two options, you
could just define common_func() as taking two additional 'int'
arguments. Passing a double or a char* would have been a better choice.

> void
> do_any();
>
> void
> common_func(int type, ...)
> {
> switch(type) {
> case 1;
> do_one(); /* pass 2,3 */
> break;


You didn't put in any of the stuff needed to actually handle variable
arguments. Was that just a simplification? Do you know how to use
<stdarg.h>?

> case 2:
> do_two(); /* pass 5,6 */
> break;
>
> default:
> do_any();
>
> }
> return;
> }
>
> int main()
> {
> comon_func(1, ,2 ,3);


The two commas between 1 and 2 are a syntax error.

> comon_func(2, ,5 ,6);


Here, too.

> }

--
James Kuyper
 
Reply With Quote
 
 
 
 
Barry Schwarz
Guest
Posts: n/a
 
      03-25-2013
Section 7.15 of n1256 describes how to do this. While not the most
current standard, the information is current and should be adequate
for your needs. You can download it from
http://www.open-std.org/jtc1/sc22/wg...docs/n1256.pdf.

On Mon, 25 Mar 2013 02:44:24 -0700 (PDT), sinbad
<(E-Mail Removed)> wrote:

>i have a common function which takes variable parameters as an argument,
>depending on the type (the first arg) i want to call the appropriate
>function with rest of the param list, is there any way to do this or
>any better approach. i'm trying to avoid the switch() statement
>below.
>
>void
>common_func(int type, ...);
>
>void
>do_one(int x, int y);
>
>void
>do_two(char a, char b);
>
>void
>do_any();
>
>void
>common_func(int type, ...)
>{
> switch(type) {
> case 1;
> do_one(); /* pass 2,3 */
> break;
>
> case 2:
> do_two(); /* pass 5,6 */
> break;
>
> default:
> do_any();
>
> }
> return;
>}
>
>int main()
>{
> comon_func(1, ,2 ,3);
> comon_func(2, ,5 ,6);
>}


--
Remove del for email
 
Reply With Quote
 
Paul N
Guest
Posts: n/a
 
      03-25-2013
On Mar 25, 9:44*am, sinbad <(E-Mail Removed)> wrote:
> i have a common function which takes variable parameters as an argument,
> depending on the type (the first arg) i want to call the appropriate
> function with rest of the param list, is there any way to do this or
> any better approach. i'm trying to avoid the switch() statement
> below.
>
> void
> common_func(int type, ...);
>
> void
> do_one(int x, int y);
>
> void
> do_two(char a, char b);
>
> void
> do_any();
>
> void
> common_func(int type, ...)
> {
> * * switch(type) {
> * * * * case 1;
> * * * * do_one(); /* pass 2,3 */
> * * * * break;
>
> * * case 2:
> * * * * do_two(); /* pass 5,6 */
> * * * * break;
>
> * * default:
> * * * * do_any();
>
> * * }
> * * return;
>
> }
>
> int main()
> {
> * * comon_func(1, ,2 ,3);
> * * comon_func(2, ,5 ,6);
> }


I think you haven't really thought through what you want. There are
times when you want a different function to be called dependent on a
value that you only know at run-time. This can be done using a switch,
or by a function pointer, amongst other possibilities.

However, here you seem to be wanting to call your common function with
different types or numbers of arguments. At the point of the call, you
have to specify the arguments, and so you apparently know at compile
time what the value of "type" is. So why not just call the function
that you want?

Hope this helps.
Paul.
 
Reply With Quote
 
sinbad
Guest
Posts: n/a
 
      03-26-2013
On Tuesday, March 26, 2013 2:05:25 AM UTC+5:30, Paul N wrote:
> On Mar 25, 9:44*am, sinbad <(E-Mail Removed)> wrote:
>
> > i have a common function which takes variable parameters as an argument,

>
> > depending on the type (the first arg) i want to call the appropriate

>
> > function with rest of the param list, is there any way to do this or

>
> > any better approach. i'm trying to avoid the switch() statement

>
> > below.

>
> >

>
> > void

>
> > common_func(int type, ...);

>
> >

>
> > void

>
> > do_one(int x, int y);

>
> >

>
> > void

>
> > do_two(char a, char b);

>
> >

>
> > void

>
> > do_any();

>
> >

>
> > void

>
> > common_func(int type, ...)

>
> > {

>
> > * * switch(type) {

>
> > * * * * case 1;

>
> > * * * * do_one(); /* pass 2,3 */

>
> > * * * * break;

>
> >

>
> > * * case 2:

>
> > * * * * do_two(); /* pass 5,6 */

>
> > * * * * break;

>
> >

>
> > * * default:

>
> > * * * * do_any();

>
> >

>
> > * * }

>
> > * * return;

>
> >

>
> > }

>
> >

>
> > int main()

>
> > {

>
> > * * comon_func(1, ,2 ,3);

>
> > * * comon_func(2, ,5 ,6);

>
> > }

>
>
>
> I think you haven't really thought through what you want. There are
>
> times when you want a different function to be called dependent on a
>
> value that you only know at run-time. This can be done using a switch,
>
> or by a function pointer, amongst other possibilities.
>
>
>
> However, here you seem to be wanting to call your common function with
>
> different types or numbers of arguments. At the point of the call, you
>
> have to specify the arguments, and so you apparently know at compile
>
> time what the value of "type" is. So why not just call the function
>
> that you want?
>
>
>
> Hope this helps.
>
> Paul.


i have many types, so the switch statement was getting
very big, i'd like to keep the functions as small as
possible. The c-standard pointed to Barry helped.
Thanks Barry. Here's what i want to do, please
point out any problems.

#include <stdio.h>
#include <stdarg.h>

void
common_func(int type, ...);

void
do_one(va_list ap);

void
do_two(va_list ap);

void
do_three(va_list ap);

void
do_any();

#define DO_MAX 4
typedef void (*do_fn)(va_list ap);

do_fn do_fns[DO_MAX];

typedef struct new {
int a;
char b;
}new_t;

void
do_one(va_list ap)
{
int x;
int y;

printf("doing one()\n");

x = va_arg(ap, int);
y = va_arg(ap, int);

printf("x is %u y is %u\n", x, y);

return;
}

void
do_two(va_list ap)
{
char a;
char b;

printf("doing two()\n");

a = va_arg(ap, int);
b = va_arg(ap, int);

printf("a is %c b is %c\n", a, b);

return;
}

void
do_three(va_list ap)
{
new_t *new;
char *c;
int *p;
void *v;

printf("doing three()\n");

c = va_arg(ap, char*);
p = va_arg(ap, int*);
v = va_arg(ap, void*);
new = va_arg(ap, new_t*);

printf("c is %p\n p is %p\n v is %p\n new is %p\n",
c, p, v, new );
return;
}

void
common_func(int type, ...)
{
va_list ap;

va_start(ap, type);

if ((type > 0) && (type < DO_MAX) && do_fns[type]) {
do_fns[type](ap);
}

va_end(ap);
return;
}

int main()
{
new_t *new = (new_t*) 0x2000;
char *c = (char*) 0x4000;
int *p = (int*) 0x8000;
void *v = (void*) 0x9000;

do_fns[0] = NULL;
do_fns[1] = do_one;
do_fns[2] = do_two;
do_fns[3] = do_three;
do_fns[DO_MAX] = NULL;

common_func(1, 2 ,3);
common_func(2, 'a' ,'b');
common_func(3, c, p , v, new);

return(0);
}

 
Reply With Quote
 
Paul N
Guest
Posts: n/a
 
      03-26-2013
On Mar 26, 6:28*am, sinbad <(E-Mail Removed)> wrote:
> On Tuesday, March 26, 2013 2:05:25 AM UTC+5:30, Paul N wrote:
> > On Mar 25, 9:44*am, sinbad <(E-Mail Removed)> wrote:

>
> > > i have a common function which takes variable parameters as an argument,

>
> > > depending on the type (the first arg) i want to call the appropriate

>
> > > function with rest of the param list, is there any way to do this or

>
> > > any better approach. i'm trying to avoid the switch() statement

>
> > > below.

>
> > > void

>
> > > common_func(int type, ...);

>
> > > void

>
> > > do_one(int x, int y);

>
> > > void

>
> > > do_two(char a, char b);

>
> > > void

>
> > > do_any();

>
> > > void

>
> > > common_func(int type, ...)

>
> > > {

>
> > > * * switch(type) {

>
> > > * * * * case 1;

>
> > > * * * * do_one(); /* pass 2,3 */

>
> > > * * * * break;

>
> > > * * case 2:

>
> > > * * * * do_two(); /* pass 5,6 */

>
> > > * * * * break;

>
> > > * * default:

>
> > > * * * * do_any();

>
> > > * * }

>
> > > * * return;

>
> > > }

>
> > > int main()

>
> > > {

>
> > > * * comon_func(1, ,2 ,3);

>
> > > * * comon_func(2, ,5 ,6);

>
> > > }

>
> > I think you haven't really thought through what you want. There are

>
> > times when you want a different function to be called dependent on a

>
> > value that you only know at run-time. This can be done using a switch,

>
> > or by a function pointer, amongst other possibilities.

>
> > However, here you seem to be wanting to call your common function with

>
> > different types or numbers of arguments. At the point of the call, you

>
> > have to specify the arguments, and so you apparently know at compile

>
> > time what the value of "type" is. So why not just call the function

>
> > that you want?

>
> > Hope this helps.

>
> > Paul.

>
> i have many types, so the switch statement was getting
> very big, i'd like to keep the functions as small as
> possible. The c-standard pointed to Barry helped.
> Thanks Barry. Here's what i want to do, please
> point out any problems.
>
> #include <stdio.h>
> #include <stdarg.h>
>
> void
> common_func(int type, ...);
>
> void
> do_one(va_list ap);
>
> void
> do_two(va_list ap);
>
> void
> do_three(va_list ap);
>
> void
> do_any();
>
> #define DO_MAX 4
> typedef void (*do_fn)(va_list ap);
>
> do_fn do_fns[DO_MAX];
>
> typedef struct new *{
> * * int a;
> * * char b;
>
> }new_t;
>
> void
> do_one(va_list ap)
> {
> * * int x;
> * * int y;
>
> * * printf("doing one()\n");
>
> * * x = va_arg(ap, int);
> * * y = va_arg(ap, int);
>
> * * printf("x is %u y is %u\n", x, y);
>
> * * return;
>
> }
>
> void
> do_two(va_list ap)
> {
> * * char a;
> * * char b;
>
> * * printf("doing two()\n");
>
> * * a = va_arg(ap, int);
> * * b = va_arg(ap, int);
>
> * * printf("a is %c b is %c\n", a, b);
>
> * * return;
>
> }
>
> void
> do_three(va_list ap)
> {
> * * new_t *new;
> * * char **c;
> * * int * *p;
> * * void **v;
>
> * * printf("doing three()\n");
>
> * * c * = va_arg(ap, char*);
> * * p * = va_arg(ap, int*);
> * * v * = va_arg(ap, void*);
> * * new = va_arg(ap, new_t*);
>
> * * printf("c is %p\n p is %p\n v is %p\n new is %p\n",
> * * * * * *c, p, v, new );
> * * return;
>
> }
>
> void
> common_func(int type, ...)
> {
> * * va_list ap;
>
> * * va_start(ap, type);
>
> * * if ((type > 0) && (type < DO_MAX) && do_fns[type]) {
> * * * * do_fns[type](ap);
> * * }
>
> * * va_end(ap);
> * * return;
>
> }
>
> int main()
> {
> * * new_t *new = (new_t*) 0x2000;
> * * char **c * = (char*) *0x4000;
> * * int * *p * = (int*) * 0x8000;
> * * void **v * = (void*) *0x9000;
>
> * * do_fns[0] * * *= NULL;
> * * do_fns[1] * * *= do_one;
> * * do_fns[2] * * *= do_two;
> * * do_fns[3] * * *= do_three;
> * * do_fns[DO_MAX] = NULL;
>
> * * common_func(1, 2 ,3);
> * * common_func(2, 'a' ,'b');
> * * common_func(3, c, p , v, new);
>
> * * return(0);
>
>
>
> }


I haven't checked in detail, but at a quick glance, yes that looks
right and is what you were asking for.

It's still a mystery to me why you need to make all the calls through
the same function "common_func", since your program apparently knows
which function it wants to call. I was just suggesting that you
consider whether this is actually required.

 
Reply With Quote
 
sinbad
Guest
Posts: n/a
 
      03-28-2013
Paul,

the common_func() does some more functionality which
is common to all the do_ functions, and it also allows
me to browse through all the instances where the do_
funcrtionality is invoked, meaning it's easy to browse
the code to check where all it is called, that is one
more reason why i want to use common_func.

-sinbad
 
Reply With Quote
 
Mark Bluemel
Guest
Posts: n/a
 
      03-28-2013
On 28/03/2013 08:03, sinbad wrote:
> Paul,
>
> the common_func() does some more functionality which
> is common to all the do_ functions,


So split the common functionality out and call it from all the do_
functions.

and it also allows
> me to browse through all the instances where the do_
> funcrtionality is invoked, meaning it's easy to browse
> the code to check where all it is called, that is one
> more reason why i want to use common_func.


Which, being translated, means "I am going to artificially structure my
code to suit some spurious measure of programmer convenience, rather
than structure it based on function".

Hint: http://en.wikipedia.org/wiki/Ctags

 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      03-29-2013
On Thu, 28 Mar 2013 09:05:20 -0400, Richard Damon
<(E-Mail Removed)> wrote:

>On 3/28/13 4:03 AM, sinbad wrote:
>> Paul,
>>
>> the common_func() does some more functionality which
>> is common to all the do_ functions, and it also allows
>> me to browse through all the instances where the do_
>> funcrtionality is invoked, meaning it's easy to browse
>> the code to check where all it is called, that is one
>> more reason why i want to use common_func.
>>
>> -sinbad
>>

>
>The problem is fundamental. The C language does not provide a method to
>pass the ... arguments to another function as arguments.


Sure it does. In C99, it is in paragraph 7.15 of n1256

--
Remove del for email
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Bit check using function check(var,pos) ((var)&(1<<pos)) prati C Programming 0 10-27-2012 05:25 PM
C++0x -- fun(Args&...) and fun(Args const&...) er C++ 2 12-20-2010 07:52 PM
Is there a class or method to construct url args or extract url args? Ken Varn ASP .Net 2 06-22-2005 12:26 PM
args v. *args passed to: os.path.join() Pierre Fortin Python 2 09-18-2004 06:59 PM
When passing functions as args,how to pass extra args for passed function? python@sarcastic-horse.com Python 3 09-17-2003 12:25 AM



Advertisments