My first questions in I don't know how long ...
I've used the various va_xxxx macros previously to handle passing
varying arguments to things like vsprintf and vsnprintf and I've used
them to handle multiple parameters but always when one of the prior
fixed arguments indicated how many extra arguments are expected. For
example, in the format string for the printf series of procedures the
number of substitution values indicates the number of expected
arguments.
I've just been doing a bunch of stuff with C and thought it would be
useful to make use of optional parameters on various procedure
interfaces. I defined a bunch of procedures with fixed parameters
followed by an ellipsis to indicate optional parameters. In each
procedure I declared a va_list and used va_start, va_arg, va_end to
extract the additional parameters.
However, I find this to be unsafe in practice because the C compiler
does not provide a way to terminate an argument list. Thus if a
function is defined as:
int doStuff( int p1, ... )
where ... could be any number of parameters there is no way for the
callee to KNOW whether a given parameter was actually passed. In the
callee we could code:
va_list ap;
int p2 = 0;
char * p3 = NULL;
double p4 = 0.0;
va_start( ap, p1 );
p2 = va_arg( ap, int );
p3 = va_arg( ap, char * );
p4 = va_arg( ap, double );
If the caller invokes doStuff and specifies all 3 additional
arguments everything works as expected. However if doStuff is invoked
with fewer than the full complement of parameters whether the code
works is entirely due to what happens to be on the stack at the time
of the call. Even if the caller does:
rc = doStuff( 100 );
p2, p3, and p4 may be set to values that are entirely incorrect due
to pointers or values existing on the stack after p1 from a prior
call to some other unrelated procedure.
None of my C references mention this potential problem. It sort of
makes sense given how little the C compiler actually does for the
developer. The various references always talk about a "varying number
of arguments" and never about "optional" parameters. None of the
references explicitly state that the caller MUST provide some means
for the callee to know how many parameters to expect. For the C
library family of printf functions this is handled implicitly by the
format string. The number of %-prefixed substitution values indicates
the number of parameters to expect. I am aware that passing fewer
arguments than substitution values will result in unpredictable
behaviour but I had not followed that through to its obvious conclusion.
I hesitate to use the word reasonable regarding anything to do with
C--such an excremental language-- but surely this is not reasonable
behaviour?
Is this how all C compilers work or only the OS/400 one?
Is this a side-effect of V5 and above using the AIX C compiler code-
base or would this behaviour occur in the previous native C compiler?
I have always thought that requiring at least one fixed parameter
prior to the variable argument list was a remarkably short-sighted
design.
Net effect of this behaviour is that C does not support "optional"
parameters.
Seems my only solutions are:
1) Include a fixed parameter for "number of additional parameters"
or
2) Drop any attempted support for "optional" parameters and require
the caller to pass NULL or 0 when they don't want to pass a real value.
Both of these approaches result in ugly and clumsy interfaces.
Can anyone suggest a better solution apart from the obvious one of
using a language with better support for optional parameters such as
RPG IV?
Regards,
Simon Coulter.
--------------------------------------------------------------------
FlyByNight Software OS/400, i5/OS Technical Specialists
http://www.flybynight.com.au/
Phone: +61 2 6657 8251 Mobile: +61 0411 091 400 /"\
Fax: +61 2 6657 8251 \ /
X
ASCII Ribbon campaign against HTML E-Mail / \
--------------------------------------------------------------------
As an Amazon Associate we earn from qualifying purchases.