Ben Combee (Tue, 19 Jun 2001 07:24:16) wrote:
-------------------
The problem is that va_arg(argp, unsigned char) is never meaningful.
Arguments pushed onto the stack for variable argument list functions are
always at least sizeof(int) bytes. If you have a parameter you want to treat
as unsigned char, you can read it off as unsigned int, then downcast. The
compiler won't push just one byte -- it will have converted any expressions
to at least int before pushing.
--------
Ben,
Thank you for the clarification. It enabled me to come up with the
following replacement for va_arg and explanation, which I include in hope of
assisting other Palm developers. Please let us know if you see a problem
with it. I find I need to support code that expects va_arg(argp, unsigned
short) to work.
I couldn't find any restrictions mentioned on the type argument for va_arg
in the Palm SDK, companion docs, the Ansi standard or the docs that came
with CW7 from Metrowerks. Tech support also seemed unaware of this. I say
all this in appreciation of how quickly you set me straight relative to my
other sources.
Again I thank you,
-- Chuck
/*
#define va_arg(ptr, type) (sizeof(type) >= sizeof(int) \
? ( (((type*)ptr)++ ), (type)(*(((type*)ptr)-1)) ) \
: ( (((int*)ptr)++ ), (type)(*(((int*)ptr)-1)) ) )
*/
/* for Ansi-strict, you need to spell out that first part */
#define va_arg(ptr, type) (sizeof(type) >= sizeof(int) \
? ( (ptr = ((char*) (((unsigned long)ptr) + sizeof(type)))),
(type)(*(((type*)ptr)-1)) ) \
: ( (ptr = ((char*) (((unsigned long)ptr) + sizeof(int )))),
(type)(*(((int*)ptr)-1)) ) )
/* va_arg(ptr, type)
Returns the value at ptr and advances ptr past that value.
Note for those new to va_arg:
This is effectively
1) cast ptr to type*
2) dereference ptr to get value
3) increment ptr
4) return value.
It looks strange because the dereference and post-increment operators
don't work together for this case.
*(((type*)ptr)++) [1,3,2] derefrences a value too far.
(*((type*)ptr))++ [1,2,3] increments the dereferenced value, not ptr.
So we wind up with 1,3,1,decrement-to-undo-step-3,2,4 instead,
which looks like the lobster quadrille ;-)
Note for those using Codewarrior for PalmOS:
Arguments put on the va stack by the ... prototype are at least sizeof(int).
So, short (when ints are 4 bytes) and byte arguments are promoted to int.
This version of va_arg handles always advances ptr by at least sizeof(int).
*/
--
For information on using the Palm Developer Forums, or to unsubscribe, please see
http://www.palmos.com/dev/tech/support/forums/