425,665 Members | 1,761 Online
Need help? Post your question and get tips & solutions from a community of 425,665 IT Pros & Developers. It's quick & easy.

# Creative uses for variable argument list functions

 P: n/a Every time I've seen an example of a variable argument list function its functionality was to print formatted output. Does anyone have examples where the function is not some variation of printf ? Jul 30 '07 #1
19 Replies

 P: n/a Spiros Bousbouras said: Every time I've seen an example of a variable argument list function its functionality was to print formatted output. Does anyone have examples where the function is not some variation of printf ? What a curious question! Well, let's see... It's easy to come up with examples, of course - but rather harder to come up with examples that might actually be useful. For example, one might calculate a sum using 0 as a terminator (since 0 doesn't affect the sum, this is not unreasonable), but why bother? One might just as easily write a routine that sums the first n items in an array, which would be far more useful. I suspect that, if there is a good answer to your question, it might lie in the realms of expression-parsing or something along those lines. I look forward to reading other answers, hopefully from people who are thinking more creatively than me today. -- Richard Heathfield Email: -www. +rjh@ Google users: "Usenet is a strange place" - dmr 29 July 1999 Jul 30 '07 #2

 P: n/a In article , Richard Heathfield Spiros Bousbouras said: >Every time I've seen an example of a variable argument listfunction its functionality was to print formatted output. Doesanyone have examples where the function is not some variationof printf ? What a curious question! Well, let's see...It's easy to come up with examples, of course - but rather harder tocome up with examples that might actually be useful. For example, onemight calculate a sum using 0 as a terminator (since 0 doesn't affectthe sum, this is not unreasonable), but why bother? One might just aseasily write a routine that sums the first n items in an array, whichwould be far more useful.I suspect that, if there is a good answer to your question, it might liein the realms of expression-parsing or something along those lines.I look forward to reading other answers, hopefully from people who arethinking more creatively than me today. The one time I used this was to write a "max" function, that would return the maximum value from a list of numbers. Jul 30 '07 #3

 P: n/a Spiros Bousbouras wrote: > Every time I've seen an example of a variable argument list function its functionality was to print formatted output. Does anyone have examples where the function is not some variation of printf ? How about a version of strcat() that takes a list of strings, which could be called like this: StrCatList(MyBuffer,MyBufferLen,string1,string2,st ring3,NULL); Yes, one could use sprintf() for this, but strcat-like functionality is (most likely) more efficient. -- +-------------------------+--------------------+-----------------------+ | Kenneth J. Brody | www.hvcomputer.com | #include | | kenbrody/at\spamcop.net | www.fptech.com | Jul 30 '07 #4

 P: n/a On Jul 30, 12:38 pm, Spiros Bousbouras

 P: n/a Kenneth Brody said: Spiros Bousbouras wrote: >>Every time I've seen an example of a variable argument listfunction its functionality was to print formatted output. Doesanyone have examples where the function is not some variationof printf ? How about a version of strcat() that takes a list of strings, which could be called like this: StrCatList(MyBuffer,MyBufferLen,string1,string2,st ring3,NULL); Yes, one could use sprintf() for this, but strcat-like functionality is (most likely) more efficient. Since it's my day for being dense, I suppose I might as well attract some flak for messing up the implementation: #include #include int catstrlist(char *buf, size_t len, ...) { int rc = 1; /* insufficient memory */ const char *arg = ""; va_list ap = {0}; va_start(ap, len); while(len 1 && arg != NULL) { if(*arg == '\0') { arg = va_arg(ap, const char *); } else { *buf++ = *arg++; --len; } } *buf = '\0'; if(arg == NULL) { rc = 0; /* all done successfully */ } va_end(ap); return rc; } /* driver */ #include #include int main(void) { int rc = 0; char target[32] = {0}; rc = catstrlist(target, sizeof target, "Hello", "World", NULL); printf("Expected [HelloWorld], " "got [%s]: Expected 0, got %d\n", target, rc); memset(target, 0, sizeof target); rc = catstrlist(target, sizeof target, "Now", "Is", "The", "Hour", NULL); printf("Expected [NowIsTheHour], " "got [%s]: Expected 0, got %d\n", target, rc); memset(target, 0, sizeof target); rc = catstrlist(target, sizeof target, "WayTooManyInputCharacters", "In", "This", "Sequence", NULL); printf("Expected [WayTooManyInputCharactersInThis], " "got [%s]: Expected 1, got %d\n", target, rc); return 0; } -- Richard Heathfield Email: -www. +rjh@ Google users: "Usenet is a strange place" - dmr 29 July 1999 Jul 30 '07 #6

 P: n/a Kenneth Brody wrote On 07/30/07 13:33,: Spiros Bousbouras wrote: >>Every time I've seen an example of a variable argument listfunction its functionality was to print formatted output. Doesanyone have examples where the function is not some variationof printf ? How about a version of strcat() that takes a list of strings, which could be called like this: StrCatList(MyBuffer,MyBufferLen,string1,string2,st ring3,NULL); Side-issue: Question 5.2 in the comp.lang.c Frequently Asked Questions (FAQ) list

 P: n/a On Jul 30, 8:38 am, Spiros Bousbouras

 P: n/a "Spiros Bousbouras"

 P: n/a In article <11**********************@d30g2000prg.googlegroups .com>, dan I got thinking the same thing recently. Can variable argument listfunctions be used to make a function able to handle int, long, orfloat, depending on what is passed? As a simple example, a MAXfunction, as someone else mentioned, that could deal with differentnumber types. Yes, but keep in mind that the mechanisms have no inherent way to find out what the type of the passed variable was, and so must be told (and so must hope that the teller didn't accidently misrepresent the types.) For example, you could have GenericOutputType MYMAX(argtypeindicator, ...) GenericOutputType perhaps being void* or a union type -- something allowing you to return different types depending on the inputs. -- Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson Jul 30 '07 #10

 P: n/a dan wrote: On Jul 30, 8:38 am, Spiros Bousbouras Every time I've seen an example of a variable argument listfunction its functionality was to print formatted output. Doesanyone have examples where the function is not some variationof printf ? I got thinking the same thing recently. Can variable argument list functions be used to make a function able to handle int, long, or float, depending on what is passed? As a simple example, a MAX function, as someone else mentioned, that could deal with different number types. I'd rather implement this functionality through void * and an extra type parameter. Is yes, would that be a good idea, or just better to write separate functions? Separate functions might be the most flexible option. Jul 30 '07 #11

 P: n/a dan wrote On 07/30/07 14:52,: On Jul 30, 8:38 am, Spiros Bousbouras >Every time I've seen an example of a variable argument listfunction its functionality was to print formatted output. Doesanyone have examples where the function is not some variationof printf ? I got thinking the same thing recently. Can variable argument list functions be used to make a function able to handle int, long, or float, depending on what is passed? As a simple example, a MAX function, as someone else mentioned, that could deal with different number types. Yes, you could write such a function. But note that there is no "auto-detection" of the argument types; you must find some way to tell the function what kind(s) of arguments it has received. You could pass a first argument that's a code for the type of the others, for example. Other problems: The compiler doesn't know that you're supposed to pass three arguments, and will be happy to accept MAX(INTTYPE, 3, 4, 5) or MAX(DBLTYPE, 2.0) or even MAX(LONGTYPE). Equally, the compiler will be happy to accept MAX(LONGTYPE, 42, 42.0). Also, the function can only return values of one type; you could make a union of int/long/double, but there's no way for the the function to return a plain int for one call and a double for another. Variable argument lists do not equal "overloading." Is yes, would that be a good idea, or just better to write separate functions? Separate functions, by all means. -- Er*********@sun.com Jul 30 '07 #12

 P: n/a Spiros Bousbouras wrote: >Every time I've seen an example of a variable argument listfunction its functionality was to print formatted output. Doesanyone have examples where the function is not some variationof printf ? A command interpreter for a simple test harness: command mandatory_1st_param optional_parameters... The parameters could be integers, a few predefined strings (RESET, CALIBRATE, etc.) translated to numeric codes, or arbitrary character strings to be passed to lower level logic (C0=24.53). First implementation begun parsing the parameters, classifying them by type and building the equivalent of a printf() format string to describe them before calling their handlers using varargs. Was short lived, changed the handlers to use a single parameter: a worst-case sized array of structures with a field for each possible parameter type and a special "end of list" struct. Was much easier to maintain than the varargs version. This is not too far removed from being "some variation of printf" ... Roberto Waltman [ Please reply to the group, return address is invalid ] Jul 30 '07 #13

 P: n/a Richard Heathfield wrote: > Kenneth Brody said: Spiros Bousbouras wrote: > Every time I've seen an example of a variable argument list function its functionality was to print formatted output. Does anyone have examples where the function is not some variation of printf ? How about a version of strcat() that takes a list of strings, which could be called like this: StrCatList(MyBuffer,MyBufferLen,string1,string2,st ring3,NULL); Yes, one could use sprintf() for this, but strcat-like functionality is (most likely) more efficient. Since it's my day for being dense, I suppose I might as well attract some flak for messing up the implementation: #include #include int catstrlist(char *buf, size_t len, ...) I was originally going to call mine "strcatlist()" but then recalled that the Standard reserves functions that start with "str" and a lowercase letter. [...] memset(target, 0, sizeof target); Wouldn't "target[0] = '\0';" suffice? rc = catstrlist(target, sizeof target, "Now", "Is", "The", "Hour", NULL); [...] -- +-------------------------+--------------------+-----------------------+ | Kenneth J. Brody | www.hvcomputer.com | #include | | kenbrody/at\spamcop.net | www.fptech.com | Jul 30 '07 #14

 P: n/a "Spiros Bousbouras"

 P: n/a Kenneth Brody said: Richard Heathfield wrote: >>Kenneth Brody said: Spiros Bousbouras wrote:Every time I've seen an example of a variable argument listfunction its functionality was to print formatted output. Doesanyone have examples where the function is not some variationof printf ? How about a version of strcat() that takes a list of strings, which could be called like this: StrCatList(MyBuffer,MyBufferLen,string1,string2,st ring3,NULL); Yes, one could use sprintf() for this, but strcat-like functionality is (most likely) more efficient. Since it's my day for being dense, I suppose I might as well attractsome flak for messing up the implementation:#include #include int catstrlist(char *buf, size_t len, ...) I was originally going to call mine "strcatlist()" but then recalled that the Standard reserves functions that start with "str" and a lowercase letter. Yay me! I actually got something right. :-) [...] > memset(target, 0, sizeof target); Wouldn't "target[0] = '\0';" suffice? Planning ahead. I was expecting problems, given the kind of day I'm having, and this was a "make sure we know the value of ***everything*** before we actually make the call" thing. -- Richard Heathfield Email: -www. +rjh@ Google users: "Usenet is a strange place" - dmr 29 July 1999 Jul 30 '07 #16

 P: n/a (I have not actually run this, but it looks correct aside from the bug I am about to note) In article <4P*********************@bt.com> Richard Heathfield Since it's my day for being dense, I suppose I might as well attractsome flak for messing up the implementation: [much snippage] >int catstrlist(char *buf, size_t len, ...) [and] rc = catstrlist(target, sizeof target, "Hello", "World", NULL); The macro NULL can be defined as plain 0 or as ((void *)0) (or in a number of other more-or-less equivalent ways). If it is defined as ((void *)0), the call above squeaks by on a technicality: (void *)0 and (char *)0 are necessarily "the same" in some fundamental sense, which probably extends to function calls. If NULL is defined as plain 0, however, the call can fail -- and does in fact fail, sometimes, on some implementations, such as those with 32-bit-int and 64-bit-pointer. The call *should* read, e.g.: rc = catstrlist(target, sizeof target, "Hello", "World", (char *)NULL); This is one of those rare cases where a cast is a good idea. It may be an even better idea to "wrap up" the cast into a #define: #define END_CATSTRLIST ((char *)NULL) ... result = catstrlist(target, sizeof target, "Hello", "World", END_CATSTRLIST); (On another note, this kind of variable-argument-list was in fact used in SunTools / SunWindows, back in its days. The variable arguments were tag-and-value pairs, and I think there was a defined tag meaning "end of tag/value pairs, and no value supplied this time".) -- In-Real-Life: Chris Torek, Wind River Systems Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603 email: forget about it http://web.torek.net/torek/index.html Reading email is like searching for food in the garbage, thanks to spammers. Jul 30 '07 #17

 P: n/a Chris Torek said: (I have not actually run this, but it looks correct aside from the bug I am about to note) I told you it wasn't my day, didn't I? Thanks, Chris. -- Richard Heathfield Email: -www. +rjh@ Google users: "Usenet is a strange place" - dmr 29 July 1999 Jul 30 '07 #18

 P: n/a Groovy hepcat Spiros Bousbouras was jivin' in comp.lang.c on Tue, 31 Jul 2007 2:38 am. It's a cool scene! Dig it. Every time I've seen an example of a variable argument list function its functionality was to print formatted output. Does anyone have examples where the function is not some variation of printf ? I have a function that merges (copies of) multiple linked lists. The prototype is this: struct dl_list_t *dl_MergeLists(size_t num, ...); The first argument represents the number of linked lists to merge. subsequent arguments must be of type struct dl_list_t *, and represent the linked lists to merge. The function makes copies of each of the linked list nodes, and stores them in a new linked list. It returns a struct dl_list_t * representing the new list. -- Dig the sig! ----------- Peter 'Shaggy' Haywood ------------ Ain't I'm a dawg!! Aug 4 '07 #19

 P: n/a On Mon, 30 Jul 2007 16:38:44 -0000, Spiros Bousbouras If I assume you meant to exclude both of those, in the Unix (POSIX) world, there's execl* as already noted, and also open() which uses it to make the third argument "optional" -- it is only used, and need only be provided, if (O_CREAT is specified and) the file is created. - formerly david.thompson1 || achar(64) || worldnet.att.net Aug 26 '07 #20

### This discussion thread is closed

Replies have been disabled for this discussion.