Museum

Home

Lab Overview

Retrotechnology Articles

⇒ Online Manual

Media Vault

Software Library

Restoration Projects

Artifacts Sought

VARARGS(5)  —  Stardent Computer Inc.

NAME

varargs − get variable argument lists

SYNOPSIS

# include <varargs.h> va_alist va_dcl void va_start(pvar)
va_list pvar; type va_arg(pvar,type)
va_list pvar; type ∗va_argp(pvar,type)
va_list pvar;

DESCRIPTION

This set of macros allows portable procedures to be written that accept variable argument lits.  Routines that have variable argument lists [such as printf(3S)] but do not use varargs are inherently nonportable, as different machines use different argument-passing conventions.  va_alist is used as the parameter list in a function header.  va_dcl is a declaration for va_alist.  va_list is a type defined for the variable used to traverse the list.  va_start is called to initialize pvar to the beginning of the list.  va_arg returns the next argument in the list pointed to by pvar. type is the type the argument is expected to be.  Different types can be mixed, but it is up to the routine to know what type of argument is expected, as it cannot be determined at runtime.  va_end is used to clean up.  Multiple traversals, each bracketed by va_start ... va_end, are possible.  In addition to the above, portable features, there are several features that are specific to the Stardent 1500/3000:

va_argp(pvar,type) is used to return a pointer to the next argument, stored in memory. 

va_doublep(pvar) is used to get pointers to double precision values (see below). 

EXAMPLE

This example shows a possible portable implementation of execl(2).  #include <varargs.h>
#define MAXARGS 100 /∗ execl is called by
execl( file, arg1, arg2, ..., (char ∗)0 );
∗/ execl(va_dcl va_alist)
{
va_list ap; char ∗file;
char ∗args[MAXARGS];
int argno = 0; va_start(ap);
file = va_arg(ap,char ∗);
while((args[argno++] = va_arg(ap,char ∗)) != (char ∗)0)
;
va_end(ap);
return execv(file,args);
} On the Stardent 1500/3000, the first four integer/pointer arguments and the first (two doubles on P3; four doubles on P2) four float/double function arguments are passed in registers.  This complicates the implementation of varargs.  In particular, a function that uses varargs will always assume that it might have floating point arguments passed to it, and will save the floating point registers.  Under some circumstances (such as the execl example, above) we know that the defined function can never be passed a floating-point number.  In this case, the pragma #pragma NO_FLOAT at the head of the file will suppress the use of floating point.  Note that this pragma affects the entire file in which it appears. Under even more obscure circumstances (e.g., printf ), it is desirable to avoid using floating point operations until you are certain that a floating point computation is being done.  This can be done by postponing the storing of the floating point registers until you are certain that floating point will be used (e.g., when a % f format is encountered).  In this case, the NO_FLOAT pragma can be used in the routine where the varargs is seen; this routine must then call another routine (compiled without NO_FLOAT), passing it the va_list variable, and this routine can then use va_doublep to obtain the double precision values.  This manual page is too small to contain all the details.

September 29, 2021

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026