va_copy implementation

S

Servé Lau

What would be a good implementation of va_copy where va_list is a typedef
for char *?

Can I jyust copy the pointer's value or is it impossible to tell without
knowing more details?
 
C

Chris Torek

What would be a good implementation of va_copy where va_list is a typedef
for char *?

Can I jyust copy the pointer's value or is it impossible to tell without
knowing more details?

I think the word "impossible" is too strong, because there are only
a few "typical" implementations for variadic functions in C. Given
the claim that "va_list" is just "char *", it is *likely* that
simply copying the value suffices. It is not guaranteed, though.

The C99 standard requires that va_copy be implemented as a macro,
so if your goal is to achieve va_copy on both C89 and C99 systems,
you can resort to something like:

#ifndef va_copy

/* WARNING - DANGER - ASSUMES TYPICAL STACK MACHINE */
#define va_copy(dst, src) ((void)((dst) = (src)))

#endif

You can dress up the "#define" in further #ifdefs to check for
known machine types (e.g., the usual powerpc va_copy is more
complicated), or you can just require that anyone porting the
software provide a "machdep/stdarg.h" header or some such, that
uses the existing C99 <stdarg.h> if it exists, or else adds the
C99 va_copy() macro atop the existing C89 <stdarg.h>.

Also, you could write a test program that "experiments with" any
va_copy you define, to see if a simple "copy the value bits" approach
works. If you pass integers (int and long and, in C99, long long;
char and short widen), floating-point values (double and long
double; float widens), and several different types of pointers,
and can access all of those correctly, you are probably close.
Add struct and union objects of varying sizes and you will test
the usual remaining special cases (and you may even discover that
the system-supplied <stdarg.h> breaks when va_arg is supposed to
extract a structure -- not that I know of particular systems where
this occurs; it just seems likely).
 
S

Servé Lau

Chris Torek said:
The C99 standard requires that va_copy be implemented as a macro,

Thanks for answering. FYI I did find taht va_copy and va_end do not have to
be macro's

7.15.1 from C99
The va_start and va_arg macros described in this subclause shall be
implemented

as macros, not functions. It is unspecified whether va_copy and va_end are
macros or

identifiers declared with external linkage.

so if your goal is to achieve va_copy on both C89 and C99 systems,
you can resort to something like:

#ifndef va_copy

/* WARNING - DANGER - ASSUMES TYPICAL STACK MACHINE */
#define va_copy(dst, src) ((void)((dst) = (src)))

#endif

You can dress up the "#define" in further #ifdefs to check for
known machine types (e.g., the usual powerpc va_copy is more
complicated), or you can just require that anyone porting the
software provide a "machdep/stdarg.h" header or some such, that
uses the existing C99 <stdarg.h> if it exists, or else adds the
C99 va_copy() macro atop the existing C89 <stdarg.h>.

Also, you could write a test program that "experiments with" any
va_copy you define, to see if a simple "copy the value bits" approach
works. If you pass integers (int and long and, in C99, long long;
char and short widen), floating-point values (double and long
double; float widens), and several different types of pointers,
and can access all of those correctly, you are probably close.
Add struct and union objects of varying sizes and you will test
the usual remaining special cases (and you may even discover that
the system-supplied <stdarg.h> breaks when va_arg is supposed to
extract a structure -- not that I know of particular systems where
this occurs; it just seems likely).
--
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.
 
C

Chris Torek

Thanks for answering. FYI I did find taht va_copy and va_end do not have to
be macro's

7.15.1 from C99
The va_start and va_arg macros described in this subclause shall be
implemented as macros, not functions. It is unspecified whether va_copy
and va_end are macros or identifiers declared with external linkage.

Ah -- sorry about that, I should have noted that I am still using
a C99 draft. Mine says:

7.12.1 Variable argument list access macros

[#1] The va_start, va_arg, and va_copy macros described in
this subclause shall be implemented as macros, not
functions. It is unspecified whether va_end is a macro or
an identifier declared with external linkage.

In this case -- unlike that for stdin/stdout/stderr, for instance
-- #ifdef-test-ability for va_copy might have been fairly useful
(as it can be used to test for implementations that have some C99
features, including va_copy, but are not yet C99-conforming and
hence do not define __STDC__ appropriately).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,102
Messages
2,570,645
Members
47,247
Latest member
GabrieleL2

Latest Threads

Top