fmsf
fmsf

Reputation: 37137

In pure C how can I pass a variable number of parameters into a function?

How can i pass (and access) using C, not c++, variable parameters into a function?

void foo(char* mandatory_param, char* optional_param, char* optional_param2...)

thanks

/fmsf

Upvotes: 1

Views: 828

Answers (6)

Ricardo Wolosker
Ricardo Wolosker

Reputation: 1

I have a solution that does not use VA_LIST in pure C. However, it works at 32bits only. Here, what happens is that each parameter of the call stack occupies as many bytes according to its type. It is possible to create a structure with a size larger than 4 or 8 bytes, so just align all the parameters in this structure.

int printf(void*,...);

typedef struct{
  char p[1024];
}P_CALL;

int soma(int a,int b){
  return a+b;
}

void main(){
  P_CALL
    call;
  char
    *pcall=(void*)&call;
  int
    (*f)()=soma,
    res;

  *(int*)pcall=1;
  pcall+=sizeof(void*);
  *(int*)pcall=2;
  pcall+=sizeof(void*);

  res=f(call);
  printf("%d\n",res);//3
}

Upvotes: 0

jyoungdev
jyoungdev

Reputation: 2674

In a language that does not support optional parameters directly, there are a few ways to achieve a similar effect. I will list them in order from the least versatile to the most:

  1. Create multiple overloads of the same function. As I recall, you cannot do this in C.

  2. Use variadic functions. Just Google this: http://www.google.com/search?q=variadic+function+c

  3. I recommend this: Create a "params" or "args" class (or struct in C), like this:

)

// untested C code
struct FooArgs {
    char * mandatory_param;
    char * optional_param;
    char * optional_param2;
    // add other params here;
};

and then make your method call take in a single argument:

// untested
void foo(struct fooArgs * args)

This way, as needs change, you can add parameters to fooArgs without breaking anything.

Upvotes: 1

#include <stdarg.h>

void do_sth (int foo, ...)
{
    int baz = 7;             /* "baz" argument */
    const char *xyz = "xyz"; /* "xyz" argument */

    /* Parse named parameters */
    va_list ap;
    va_start (ap, foo);
    for (;;) {
        const char *key = va_arg (ap, char *);
        if (key == NULL) {
            /* Terminator */
            break;
        } else if (strcmp (key, "baz") == 0) {
            baz = va_arg (ap, int);
        } else if (strcmp (key, "xyz") == 0) {
            xyz = va_arg (ap, char *);
        } else {
            /* Handle error */
        }
    }
    va_end (ap);

    /* do something useful */
}

do_sth (1, NULL);                             // no named parameters
do_sth (2, "baz", 12, NULL);                  // baz = 12
do_sth (3, "xyz", "foobaz", NULL);            // xyz = "foobaz"
do_sth (4, "baz", 12, "xyz", "foobaz", NULL); // baz = 12, xyz = "foobaz"

Variadic functions and arguments assignment in C/C++

Upvotes: 1

zmbush
zmbush

Reputation: 2810

It sounds like you are looking for varargs.

#include <stdarg.h>
void foo(const char *fmt, ...)
{
  va_list argp;
  va_start(argp, fmt);
  int i = va_arg(argp, int);
  // Do stuff...
  va_end(argp);
}

Upvotes: 9

Gautam Kumar
Gautam Kumar

Reputation: 1170

Read about Variable Arguments in C

Upvotes: 7

alternative
alternative

Reputation: 13012

Use stdarg.h

You need to use va_list and then use the macros va_start, va_arg, and va_end.

For more information, see http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.10.html

Upvotes: 13

Related Questions