Although variable arguments are the only way to have achieve certain goals in C, and are used in the important I/O functions printf and scanf, there are some distinct disadvantages:

- va_start and va_arg must be implemented as macros which are evil in their own right.

- There is no way to tell what type of argument is being passed in. It could be a character string, it could be an integer, it could be your Aunt Matilda. You have to assume that code that calls your routine is passing in the right type of information and hope that Aunt Matilda doesn't get hurt in the process. This defeats the entire purpose of writing in C++.

Finally, there are always other, better ways in C++ to achieve whatever goal led you to want variable arguments in the first place. Use them instead.

That's mostly true enough (especially about the satanic nature of macros), but point 2 is mushy because the C++ type system is designed to be broken anyway, and will remain so until C-style casts are removed from the language -- in other words, as long as earth and sky abide.

(That used to say "deprecated" instead of "removed from the language", but Furious George was kind enough to point out that they already are deprecated, and what I meant was something different -- and he was right, too. Ack!)

Secondly, sprintf() is indispensable because there's no other equally powerful way to format things. And how many people seriously use the iostream library? Not me. It's annoying and weak and it requires too much support in my own code for too little benefit. I'll give up my FILE * when you pry my cold dead fingers from it. Then again, I learned C first (not necessarily best) and that colors my view of things.

On the other hand, ever since I learned to use the varargs.h stuff, I've been looking for uses for it in my own code, and I've yet to find a compelling one1. Whenever it seems convenient, I aways run up against the problem of determining how many arguments are actually on the damn stack. The format string in the printf() family does the job nicely (assuming the programmer doesn't goof, which is a hell of a dangerous assumption), but without something like that, you're left with adding a dummy NULL or else making the first argument a count of the others. Both of the latter two solutions are dismal kludges. If anybody knows any others, I'd love to hear 'em.

Hm. Come to think of it, since you've got the address of the argument that was pushed last, I'm a bit fuzzy about why you can't just compare the address of any given argument to the stack pointer and know where you are without having to be told. You must be able to get the stack pointer somehow; I mean, it's C, right? So there's obviously something about that which eludes my grasp.

"there are always other, better ways"?

Them sounds like famous last words to me, ha ha.



1 The sole exception would be a sprintf()ish member of a string class, which would realloc() as needed, so it wouldn't be subject to buffer overruns. MFC's string class, CString, does that. The class is a dog in general, but boy that one feature is nifty as all heck. CString also has an odd and ill-advised kludge in it which addresses Gorgonzola's second point, and which is discussed in gruesome and drooling detail in the CString node.

Log in or register to write something here or to contact authors.