I want a function that, when called with a varying number of arguments, return the first non-NULL one. I've tried this, but it core dumps on for
loop:
char *first(char *args, ...)
{
va_list ap;
char *r = NULL, *p;
va_start(ap, args);
for (p = args; *p; p++) {
r = va_arg(ap, char*);
if (r != NULL) break;
}
va_end(ap);
return r;
}
char *q = NULL;
char *w = NULL;
char *e = "zzz";
char *r = NULL;
printf("%s\n", first(q, w, e, r)); // ought to print "zzz"
args
is not an array of arguments. It's just the first argument you passed to first
. So its value in this case is the value of q
.
You can't iterate over va args like you are doing.
Do this:
va_start(ap, args);
do {
r = va_arg(ap, char*);
if (r != NULL) break;
} while (1);
va_end(ap);
This will crash if you have no non-NULL argument, though, so you would better pass the number of arguments as first argument:
char *first(int nargs, ...)
{
char *r = NULL;
va_start(ap, nargs);
for( ; nargs; nargs--) {
r = va_arg(ap, char*);
if (r != NULL) break;
}
va_end(ap);
return r;
}
first(4, q, w, e, r);
Alternatively, use a sentinel:
char *first(char *first, ...)
{
char *r = first;
va_start(ap, first);
while (!r) {
r = va_arg(ap, char*);
}
va_end(ap);
return r == &sentinel ? NULL : r;
}
char sentinel; // its address is unique among other pointers
first(q, w, e, r, &sentinel);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With