Page 1 of 2
VA_ARG
Posted: Wed Jan 26, 2005 10:04 am
by dh
My book doesn't say how to use the VA_ARG macros so could anybody enlighten me?
Cheers, DH.
Re:VA_ARG
Posted: Wed Jan 26, 2005 11:02 pm
by Solar
Dragon_Hilord wrote:
My book doesn't say how to use the VA_ARG macros so could anybody enlighten me?
Get a better book, or the HTML library reference from
http://www.dinkumware.com, which is also available online and
says this on stdarg.h.
Re:VA_ARG
Posted: Thu Jan 27, 2005 9:42 am
by dh
@Solar: ;,,( Not exactly what I ment but thanks non-the-less!
Cheers, DH.
Re:VA_ARG
Posted: Thu Jan 27, 2005 10:03 am
by Solar
Well, the Dinkumware site comes with a usage example... if that isn't what you were looking for, tell me
what you meant, i.e. what is unclear to you, and I'll try to nail it down.
Re:VA_ARG
Posted: Thu Jan 27, 2005 11:56 am
by dh
ok, what I meant was what does the functions repersent and (was solved by you link) what order are the macros called.
By repersent, I mean: what does macro A do and how do you use it, etc.
Cheers, DH.
PS: i found the document a bit... unclear
Re:VA_ARG
Posted: Thu Jan 27, 2005 2:13 pm
by Solar
OK, I'll simplify it a bit:
Code: Select all
#include <stdarg.h>
void foo(char *s, ...)
{
va_list ap;
va_start(ap, s);
while (t = va_arg(ap, char *))
{
bar( t );
}
va_end(ap);
}
You have a function with at least one fixed argument and an elipsis. To read the variable argument list, you need an va_list object, which is declared by
va_list ap;
Then you have to initialize ap, i.e. tell it where on the stack to look for the first argument. For this, you use the last of the fixed arguments, and pass that as parameter to va_start:
va_start( ap, s );
Now, you can make sequential calls to va_arg, using the va_list object and the expected type as parameter:
t = va_arg( ap, char * )
Beware - there is no such thing as an "end of list". Your (...) function and its caller have to agree on some way to terminate the argument list (e.g. NULL pointer), as an va_arg beyond the last argument will bring death to your program.
When you're done, you call va_end for cleanup:
va_end( ap );
The last macro, va_copy, is only available for C99, and a dangerous beast if you don't know your va_args by heart, so better stay away from it first.
Re:VA_ARG
Posted: Fri Jan 28, 2005 11:18 am
by dh
@Solar: Thanks, I don't think I could OSdev w/o you! In fact, I don't think I could write anything _good_ in C without the people here at mega-tokyo!
Thanks again, DH.
Re:VA_ARG
Posted: Mon Jan 31, 2005 3:56 am
by df
always struck me as odd the way the va_args worked. you would have thought it would have pushed say 3, then 3 arguments so the functions knew how many args to safely use etc...
Re:VA_ARG
Posted: Mon Jan 31, 2005 7:53 pm
by mystran
The reason va_args works is an unfortunate result of some historical facts:
The calling convention is designed for fixed arguments. In fixed argument case any argument count would be just bloat. So we only push arguments.
Ok, so why not push the number in variable case? Because in traditional C you don't need to tell anyone anything about your arguments. If you don't have a prototype, then we must expect that your function takes any number of arguments and return int.
So we would really have to pay the price of variable arguments for EVERY function, because any function can be compiled agaist without knowing it's type. Not that this would really matter with modern machines, but since the va_args hack is already accepted the way it works, why change it anymore?
Anyway, essentially you need to push that number anyway, because you need to pass a single argument anyway, and you really use that single argument to see how many futher arguments there are. That could be made implicit, but in case of something like printf, it would be just extra bloat anyway.
Besides, if I was designing a new calling convention (or should I say when, since I'm also interested in language issues) it'd pass the number of arguments in a register instead. And I'd also put arguments ABOVE the return address and declare them callee-pop because that'd make tail-call elimination possible.
Re:VA_ARG
Posted: Tue Feb 01, 2005 3:04 am
by Solar
You have to keep in mind that C was around long before any efforts at standardization were made. It was a mess well before ANSI C came out, and they had to respect what already was common practice, or no-one would have adopted ANSI/ISO C in the first line.
As opposed to Java, which was cast in the laboratory and was "ready" when released - and made into a mess only afterwards. ;D
Re:VA_ARG
Posted: Tue Feb 01, 2005 6:03 am
by dh
Great history lesson ;D (no, really
)
Cheers, DH.
Re:VA_ARG
Posted: Tue Feb 01, 2005 9:08 am
by Solar
You should read the paragraph P.J. Plauger wrote in his book, "The C Standard Library", about the angst that struck the ANSI C committee when they learned that the ISO C committee was quite determined to have ISO C differ from ANSI C... and how they scrambled to fix the one main deficit ISO perceived in ANSI C: locales. Took them another year or so.
I can picture it. ANSI C and ISO C differing, now that would have been a fine mess for library and compiler implementors...
Re:VA_ARG
Posted: Wed Feb 02, 2005 10:37 am
by dh
@Solar: Agreed.
Re:VA_ARG
Posted: Thu Feb 03, 2005 5:21 pm
by dh
@Solar: ummm. I'm having a problem :-X... I keep getting the error that va_list doesn't exist. Also I get problems with something to do with a comma operator. When I run the preprocessor on it to see what it's doing, it appears that everything is honkey-dorie except va_list which remains the same (vim colors it like an internal command). Any input? Thanks in advance!
Cheers, DH
Re:VA_ARG
Posted: Fri Feb 04, 2005 1:53 am
by Solar
Hard to say without seeing the code.