[comp.unix.questions] problem with varargs

sm@gator.cacs.usl.edu (Srinivas Madhur) (03/26/90)

Hi netters!

I am having a problem with varargs (both on Sun 4.0 and 4.3BSD).
The example program given in the man page shows that after all
the parameters passed are read, next time va_arg is called, the
return value will be NULL which can be used as a sentinel.
I am getting the NULL value if there is *no other variable* 
defined after the actual parameter or if the paramter passed to 
the function is global. Is there any known problem with varargs
in SunOS and 4.3BSD or am I missing something obvious? If this is
a problem, what is the fix?

Please respond to me via email as I rarely read this group!
Any help would be greatly appreciated!

I am enclosing a sample program.
----------------cut here---------------------------------------

#include <varargs.h>
#include <stdio.h>
main()
{
	static char ppp[] = "message";
	char *next = "error";
	foo(ppp); <---- calling foo with only  ppp as param
			prints "message error"
}

foo(va_alist)
va_dcl
{
	va_list ap;
	char * ptr;
	va_start(ap);

	while ((ptr = va_arg(ap, char *)) != NULL)
		printf("%s  ", ptr);
	va_end(ap);
	
	printf("\n");
}

------------------------cut here--------------------------------
--
Srinivas Madhur	
sm@gator.cacs.usl.edu
sm@cacs.usl.edu
.!dalsqnt!gator!sm

jik@athena.mit.edu (Jonathan I. Kamens) (03/26/90)

In article <5810@rouge.usl.edu>, sm@gator.cacs.usl.edu (Srinivas Madhur)
writes:
> I am having a problem with varargs (both on Sun 4.0 and 4.3BSD).
> The example program given in the man page shows that after all
> the parameters passed are read, next time va_arg is called, the
> return value will be NULL which can be used as a sentinel.
> I am getting the NULL value if there is *no other variable* 
> defined after the actual parameter or if the paramter passed to 
> the function is global. Is there any known problem with varargs
> in SunOS and 4.3BSD or am I missing something obvious? If this is
> a problem, what is the fix?

  Your mistake is in assuming that "after all the parameters passed in
are read, next time va_arg is called, the return value will be NULL
which can be used as a sentinel."  In the man page on my system
(4.3BSD), the "example program" ([sic] actually it's a function, not a
program) given in the man page is execl(), which is a SPECIAL CASE in
which it is legal to expect a NULL at the end of the arg list.  From the
"BUGS" section of the man page:

     It is up to the calling routine to determine how many argu-
     ments there are, since it is not possible to determine this
     from the stack frame.  For example, execl passes a 0 to sig-
     nal the end of the list.  Printf can tell how many arguments
     are supposed to be there by the format.

  In other words, you cannot assume that the arg list which will be
returned one item at a time by va_arg will be terminated by a NULL -- if
you want it to be, then you have to so terminate it yourself when you
make the function call.

  The sample program you posted probably behaves as it does simply
because the next thing on the stack after the arguments to the foo()
function is the pointer to the variable "next" in main() -- that's just
a coincidence based on the way the stack frames and such work on the
architectures you are using.

Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8495			      Home: 617-782-0710

P.S. I am responding here, as well as mailing the answer via private
E-mail, because I believe that the question and its answer are of
general interest to other readers of this newsgroup.  Having made that
disclaimer and explained my motives, I hope I don't now get thousands of
E-mail messages flaming me for posting when the original poster asked
for E-mail responses.