Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a nicer way to do c named arguments?

I'm trying to implement a flexible debug macro/function lib and named/optional arguments seem like the best way to implement the functions.

Is there a nicer way to do named arguments in c then the following?

enum named_args {NAME,ADRESS,AGE,NA_SENTINEL};

void named_arg_initializers(struct person p, enum * named_args)
{
    enum named_args * current_name;
    enum named_args * current_arg;
    ...
    if(named_args==NULL)
        return;
    current_name = named_args[0];
    current_arg = named_args[1];
    while(current_name!=NA_SENTINEL)
    {
        current_name+=2;
        current_arg+=2;
        if(current_name==NAME)
            p.name=current_arg;
        else if(...
        ...
        }
        ...
    }
    ...
}
like image 471
Roman A. Taycher Avatar asked May 10 '11 08:05

Roman A. Taycher


People also ask

Is it better to use named or unnamed parameters in C#?

The main advantage of named arguments in C# is that we can pass the arguments out of their positional order. Simply put, we don't have to remember the order of parameters. They also increase the readability of the application, especially in cases where all the arguments are of the same type.

How do you handle a named argument in a function?

When you mix named and unnamed arguments in a function call, the unnamed arguments must come before the named ones in the argument list. Thus, when writing a function, you should put required arguments to the function in the argument list before the ones that you consider optional.

Does order of arguments matter in C?

Yes, it matters. The arguments must be given in the order the function expects them. C passes arguments by value. It has no way of associating a value with an argument other than by position.

Do parameter names and argument names have to be the same?

The caller's arguments passed to the function's parameters do not have to have the same names.


2 Answers

Sure.

struct toto {
  unsigned age;
  char name[25];
};

void func(struct toto);

...

func((struct toto){ .name = "you", .age = 18 });

or if you want you may wrap that in a macro

#define FUNC(...) func((struct toto){ __VA_ARGS__ })
...
FUNC(.name = "you", .age = 18 );
like image 110
Jens Gustedt Avatar answered Nov 15 '22 20:11

Jens Gustedt


The way you've shown isn't valid unless the named arguments are all compatible with enum (you could fix that by using a void * argument).

However, you could do something similar with varargs which looks neater:

#include <stdarg.h>

enum named_args { NAME, ADDRESS, AGE, NA_SENTINEL };

void named_arg_initializers(struct person *p, ...)
{
    va_list ap;
    enum named_args argn;

    va_start(ap, p);
    for (argn = va_arg(ap, enum named_args); argn != NA_SENTINEL; argn = va_arg(ap, enum named_args))
    {
        switch (argn)
        {
          case NAME:
            p->name = va_arg(ap, char *);
            break;

          case AGE:
            p->age = va_arg(ap, int);
            break;

          /* ...  */
         }
    }
    va_end(ap);

    /* ... */
}

You'd use it like so:

named_arg_initializers(&p, AGE, 110, NAME, "Claude Choules", NA_SENTINEL);
like image 40
caf Avatar answered Nov 15 '22 20:11

caf