Stdarg and null arguments

I need a function that, when called with a variable number of arguments, returns the first non-NULL. I tried this, but the kernel is unloaded in a 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" 
+4
source share
1 answer

args not an array of arguments. This is only the first argument that you passed first . Thus, its value in this case is the q value.

You cannot iterate through va args as you do.

Do it:

 va_start(ap, args); do { r = va_arg(ap, char*); if (r != NULL) break; } while (1); va_end(ap); 

This will crash if you don't have an argument other than NULL, so you better pass the number of arguments as the 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 signal:

 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); 
+11
source

All Articles