Click to See Complete Forum and Search --> : Platform Independence: Variable Argument Lists


MrDoomMaster
March 15th, 2006, 03:55 PM
I am interested in creating my own function which has the following shell:

void strformat(char* buffer, const char* str, ...)
{
}

I want to be able to directly read the variable arguments without actually using ANY microsoft code. I want to completely do this using C++, no API's or anything.

I mainly want to do this for educational purposes, I'm really interested in learning how this works. I'm sure there's plenty of platform independent versions of this already, but I've already mentioned that I want to know this for educational purposes.

I would appreciate any help! Thanks.

Paul McKenzie
March 15th, 2006, 04:07 PM
I'm sure there's plenty of platform independent versions of this already,Parsing a variable argument list is highly dependent on the platform. There is no platform-indepenent way of doing this.
but I've already mentioned that I want to know this for educational purposes.Well why not take a look at how your compiler or several compilers do this first? The source code to printf() should be available.

Regards,

Paul McKenzie

MrDoomMaster
March 15th, 2006, 04:43 PM
Parsing a variable argument list is highly dependent on the platform. There is no platform-indepenent way of doing this.
Well why not take a look at how your compiler or several compilers do this first? The source code to printf() should be available.

Regards,

Paul McKenzie

I guess I forgot to mention that I mean platform independence based on #ifdef logic.

Thank you for this information, Paul, I had no idea that printf and the va_ functions were 'open source'. Microsoft usually likes to hide their stuff :P

Paul McKenzie
March 15th, 2006, 05:06 PM
I guess I forgot to mention that I mean platform independence based on #ifdef logic.

Thank you for this information, Paul, I had no idea that printf and the va_ functions were 'open source'. Microsoft usually likes to hide their stuff :PIt depends on how you installed your VC++ compiler. There are options of whether you want the RTL source or not. If you don't see the RTL source code, then either you have a downgraded version of the compiler which doesn't give you the RTL source, or you didn't choose the option to install the RTL source code.

Regards,

Paul McKenzie

SuperKoko
March 15th, 2006, 05:09 PM
There is a platform independent way to access it:
<stdarg.h> (and <cstdarg> for C++).

You can get help from the single unix specification (version 2):
http://www.opengroup.org/onlinepubs/007908799/xsh/stdarg.h.html

Or, you can read the ISO C99 draft which provides information for [b]va_copy|/b]

7.15 Variable arguments <stdarg.h>
1 The header <stdarg.h> declares a type and de\ufb01nes four macros, for advancing
through a list of arguments whose number and types are not known to the called function
when it is translated.
2 A function may be called with a variable number of arguments of varying types. As
described in 6.9.1, its parameter list contains one or more parameters. The rightmost
parameter plays a special role in the access mechanism, and will be designated parmN in
this description.
3 The type declared is
va_list
which is an object type suitable for holding information needed by the macros
va_start, va_arg, va_end, and va_copy. If access to the varying arguments is
desired, the called function shall declare an object (referred to as ap in this subclause)
having type va_list. The object ap may be passed as an argument to another function;
if that function invokes the va_arg macro with parameter ap, the value of ap in the
calling function is indeterminate and shall be passed to the va_end macro prior to any
further reference to ap.199)
7.15.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 unspeci\ufb01ed whether va_end is a macro or
an identi\ufb01er declared with external linkage. If a macro de\ufb01nition is suppressed in order
to access an actual function, or a program de\ufb01nes an external identi\ufb01er with the name
va_end, the behavior is unde\ufb01ned. Each invocation of the va_start or va_copy
macros shall be matched by a corresponding invocation of the va_end macro in the
function accepting a varying number of arguments.
199) It is permitted to create a pointer to a va_list and pass that pointer to another function, in which
case the original function may make further use of the original list after the other function returns.
7.15.1.1 The va_arg macro
Synopsis
1 #include <stdarg.h>
type va_arg(va_list ap, type);
Description
2 The va_arg macro expands to an expression that has the speci\ufb01ed type and the value of
the next argument in the call. The parameter ap shall be the same as the va_list ap
initialized by va_start. Each invocation of va_arg modi\ufb01es ap so that the values of
successive arguments are returned in turn. The parameter type shall be a type name
speci\ufb01ed such that the type of a pointer to an object that has the speci\ufb01ed type can be
obtained simply by post\ufb01xing a * to type. If there is no actual next argument, or if type is
not compatible with the type of the actual next argument (as promoted according to the
default argument promotions), the behavior is unde\ufb01ned, except for the following cases:
\u2014 one type is a signed integer type, the other type is the corresponding unsigned integer
type, and the value is representable in both types;
\u2014 one type is pointer to void and the other is a pointer to a character type.
Returns
3 The \ufb01rst invocation of the va_arg macro after that of the va_start macro returns the
value of the argument after that speci\ufb01ed by parmN . Successive invocations return the
values of the remaining arguments in succession.
7.15.1.2 The va_copy macro
Synopsis
1 #include <stdarg.h>
void va_copy(va_list dest, va_list src);
Description
2 The va_copy macro makes the va_list dest be a copy of the va_list src, as if
the va_start macro had been applied to it followed by the same sequence of uses of
the va_arg macro as had previously been used to reach the present state of src.
Returns
3 The va_copy macro returns no value.
7.15.1.3 The va_end macro
Synopsis
1 #include <stdarg.h>
void va_end(va_list ap);
Description
2 The va_end macro facilitates a normal return from the function whose variable
argument list was referred to by the expansion of va_start that initialized the
va_list ap. The va_end macro may modify ap so that it is no longer usable (without
an intervening invocation of va_start). If there is no corresponding invocation of the
va_start macro, or if the va_end macro is not invoked before the return, the
behavior is unde\ufb01ned.
Returns
3 The va_end macro returns no value.
7.15.1.4 The va_start macro
Synopsis
1 #include <stdarg.h>
void va_start(va_list ap, parmN);
Description
2 The va_start macro shall be invoked before any access to the unnamed arguments.
3 The va_start macro initializes ap for subsequent use by va_arg and va_end.
va_start shall not be invoked again for the same ap without an intervening invocation
of va_end for the same ap.
4 The parameter parmN is the identi\ufb01er of the rightmost parameter in the variable
parameter list in the function de\ufb01nition (the one just before the , ...). If the parameter
parmN is declared with the register storage class, with a function or array type, or
with a type that is not compatible with the type that results after application of the default
argument promotions, the behavior is unde\ufb01ned.
Returns
5 The va_start macro returns no value.

exterminator
March 16th, 2006, 12:32 AM
Variadic functions (http://www.gnu.org/software/libc/manual/html_node/Variadic-Functions.html). In C++, you would usually not feel the need of variadic functions.. also since they cannot be used with non-POD types.. their usage is quite restrictive unless you are doing C++ in C way -- which is not the right way... Regards.