🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #4028

Re: stdargs: passing (va_list *) to worker routines

#4028
From: Paul G. Fox
Date: Mon, 18 Sep 1995 19:57
132 lines
3526 bytes
Tanmoy Bhattacharya (tanmoy@qcd.lanl.gov) wrote:
: In article <434pa4$c4c@news1.wing.net>, pgf@american.com (Paul G. Fox) writes: 
: |> 
: |> the vendor's introduction of array semantics causes my "&ap" to break.

: I do not understand this. In what context does a fully paranthesized
: expression `(*&a)' differ from `a' if `a' is an addressable lvalue?

: I believe this set of parantheses in the definition of va_arg is mandatory. 

well, i've produced a smallish self-contained example of code that breaks
when va_list is a "typedef char *va_list[1]".

the gcc error when compiling the "broken" case is:
 vaarg.c: In function `func2':
 vaarg.c:86: warning: passing arg 1 of `func3' from incompatible pointer type


paul

--------cut here---------

#include <stdio.h>

/* pick only one */
#define USE_STDARG 0
#define USE_TRADITIONAL_IMPLEMENTATION 1
#define USE_BROKEN_IMPLEMENTATION 0

#if USE_STDARG
#include <stdarg.h>
#endif

#if USE_BROKEN_IMPLEMENTATION

typedef char   *va_list[1];

#define va_start(ap,parm_n) ((ap)[0]=(char *)&parm_n+\
         ((sizeof(parm_n)+sizeof(int)-1)&~(sizeof(int)-1)))

#define va_arg(ap,type)     ((ap)[0]+=\
         ((sizeof(type)+sizeof(int)-1)&~(sizeof(int)-1)),\
         (*(type *)((ap)[0]-((sizeof(type)+sizeof(int)-1)&~(sizeof(int)-1)))))

#define va_end(ap)          ((ap)[0]=0,(void)0)

#endif

#if USE_TRADITIONAL_IMPLEMENTATION

typedef char   *va_list;

#define va_start(ap,parm_n) ((ap)=(char *)&parm_n+\
         ((sizeof(parm_n)+sizeof(int)-1)&~(sizeof(int)-1)))

#define va_arg(ap,type)     ((ap)+=\
         ((sizeof(type)+sizeof(int)-1)&~(sizeof(int)-1)),\
         (*(type *)((ap)-((sizeof(type)+sizeof(int)-1)&~(sizeof(int)-1)))))

#define va_end(ap)          ((ap)=0,(void)0)


#endif

void func3(va_list*);
void func2(va_list);
void func1(char *, ...);

int num_strings;

void
main(void)
{
	num_strings = 3;
	func1( "here's a test:\n", "one", "two", "three", 42);

	num_strings = 1;
	func1( "here's another test:\n", "one", 42);

	num_strings = 0;
	func1( "one last test:\n", 42);
}	

/* print the first arg, which is a string, and let func2() take care
	of the rest */
void
func1(char *leading_text, ...)
{
	va_list ap;

	printf("\n%s", leading_text);

	va_start(ap, leading_text);
	func2(ap);
	va_end(ap);


}

/* call func3 to print an unknown number of string arguments, then print
	the last arg, which is an integer */
void
func2(va_list ap)
{
	int i;

	func3(&ap);

	i = va_arg(ap, int);

	printf("num is %d\n", i);

}

/* print "num_strings" strings */
void
func3(va_list *app)
{
	char *s;

	while( num_strings-- ) {
		s = va_arg(*app, char *);
		printf("string is %s\n", s);
	}
}


---------------------
    paul fox                            american internet corporation
    pgf@american.com			(home: pgf@foxharp.boston.ma.us)
    "As you can see, unraveling even a small part of 'sendmail'
    can introduce more complexity than answers." --Brian Costales, _sendmail_
Technical Details
Message-ID: <43kiup$ev3@news1.wing.net>
Path: arc1-ca.pugleaf.net!news.wing.net!pgf
References: <434pa4$c4c@news1.wing.net> <435gt4$jgj@newshost.lanl.gov>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!news.wing.net!pgf
From: pgf@american.com (Paul G. Fox)
Newsgroups: comp.std.c
Subject: Re: stdargs:  passing (va_list *) to worker routines
Date: 18 Sep 1995 19:57:13 GMT
Organization: Wilder Internet Gateway, Boston, MA
Distribution: world
Message-ID: <43kiup$ev3@news1.wing.net>
References: <434pa4$c4c@news1.wing.net> <435gt4$jgj@newshost.lanl.gov>
NNTP-Posting-Host: longfellow.american.com
X-Newsreader: TIN [version 1.2 PL2]