Article View: comp.std.c
Article #4028Re: stdargs: passing (va_list *) to worker routines
From: Paul G. Fox
Date: Mon, 18 Sep 1995 19:57
Date: Mon, 18 Sep 1995 19:57
132 lines
3526 bytes
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!pgfReferences:
<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]