Named arguments in C
Just in case some madman argues that C needs them (no, of course nobody asked them from me!), here's a nice and readable way to go about it.
You can define a structure with members named appropriately:
struct params {
unsigned int count;
const unsigned char *source;
};
bool func(struct params args) {...}
Then you can call func as follows:
func((struct params){.count = 4, .source = "foo"});
This form isn't very pretty, though. Information about types is still a tag jump away, but why is that cast present? It's a little bit confusing. So how about we wrap it in a macro, such as:
#define FUNC(...) func((struct params) { __VA_ARGS__ } )
/* ... */
FUNC( .count = 4, .source = "foo" );
Well that looks neat. However, information about the function prototype is now an extra tag jump away, which is a bummer to anyone but ourselves.
To mix our version of named arguments with normal, unnamed ones we can just:
bool func(short op, struct params args) {...}
#define FUNC(x, ...) func((x), (struct params) { __VA_ARGS__ } )
/* ... */
FUNC(4, .count = 4, .source = "foo" );
Some things to consider are
- Default values. For compound literals, subobjects without explicit initializers are initialized to zero. You have to account for cases when zero is not an acceptable value for those uninitialized members. This is fine if you just skip one subobject, but probably not so much if you only care to initialize the particular element 999 in an array of size 10.000. [edit] As far as gcc & GNU extensions are concerned, though, you can use the following syntax
int widths[] = { [0 ... 9999] = 0xff}; - Mutability and persistence. Compound literals in this context have automatic storage and if you want to write some bytes in a buffer destined for the caller, for example, you have to resort to the last style of mixing "named" with regular arguments.
- The next Underhanded C Contest (what the hell happened to it, anyway?)
Cheers.