mark@DRD.Com (Mark Lawrence) (07/26/90)
I'm using gcc 1.37 or so on a Sun SparcStation running 4.0.3. I've got a function whose first three arguments should always be provided but the rest of the arguments will be handed to vsprintf for formatting. The function itself looks like: #include <stdio.h> #include <varargs.h> #include <alarms.h> /* which includes a function prototype for this func */ #define AlarmBufSz 1024 static char buf[AlarmBufSz]; /*VARARGS0*/ void ReportAlarm(va_alist) va_dcl { va_list args; AlarmType alarm; char *source; char *fmt; va_start(args); source = va_arg(args, char *); alarm = va_arg(args, AlarmType); fmt = va_arg(args, char *); (void) vsprintf(buf, fmt, args); va_end(args); /* and stuff ... */ } alarms.h looks like: #ifndef ALARMS_H #define ALARMS_H typedef enum { alNone, alFoo, alLastAlarm } AlarmType; /* void ReportAlarm(char * source, AlarmType alarm, char * fmt, ...) */ void ReportAlarm(); #endif /* ALARMS_H */ My questions are: 1) do I need to provide a terminating NULL when calling this function (I've seen it done int the Thom Plum notes on the Draft C Standard, but I've tried it in Saber without and it *seems* to work) 2) how do I prototype it? I tried the above commented out prototype and when compiling function, gcc gripes that it doesn't match its prototype and quits.
dkeisen@Gang-of-Four.Stanford.EDU (Dave Eisen) (07/26/90)
In article <1990Jul25.195944.9238@DRD.Com> mark@drd.Com (Mark Lawrence) writes: > >I've got a function whose first three arguments should always be provided >but the rest of the arguments will be handed to vsprintf for formatting. > >The function itself looks like: > [The K&R version of the function omitted for brevity] #include <stdio.h> #include <stdarg.h> /* varags is used in the K&R world, it doesn't work with prototypes */ #include <alarms.h> /* which includes a function prototype for this func */ #define AlarmBufSz 1024 static char buf[AlarmBufSz]; /* The definition of the function matches the prototype given in alarm.h */ /* This prototype is */ /* void ReportAlarm (char *source, AlarmType alarm, char *fmt, ...); */ /*VARARGS3*/ void ReportAlarm(char *source, AlarmType alarm, char *fmt, ...) { va_list args; va_start(args, format); /* va_start now takes the last required function parameter as its second argumnet. */ (void) vsprintf(buf, fmt, args); va_end(args); /* Other stuff ... */ } -- Dave Eisen Home: (415) 323-9757 dkeisen@Gang-of-Four.Stanford.EDU Office: (415) 967-5644 1447 N. Shoreline Blvd. Mountain View, CA 94043
karl@haddock.ima.isc.com (Karl Heuer) (07/27/90)
In article <1990Jul25.195944.9238@DRD.Com> mark@drd.Com (Mark Lawrence) writes: >[A function defined with the <varargs.h> macros fails to match its prototype] Don't use <varargs.h> in ANSI C. Use <stdarg.h> instead. >do I need to provide a terminating NULL when calling this function Not in this case. The function that ultimately parses the variadic part is vsprintf, and it uses the format string, rather than a sentinel value, to detect the end of the list. Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint