124 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
| .\"	@(#)varargs.3	6.3 (Berkeley) 5/15/86
 | |
| .\"
 | |
| .TH STDARG 3  "May 15, 1986"
 | |
| .AT 3
 | |
| .SH NAME
 | |
| stdarg \- variable argument list
 | |
| .SH SYNOPSIS
 | |
| .nf
 | |
| .ft B
 | |
| #include <stdarg.h>
 | |
| 
 | |
| void va_start(va_list \fIap\fP, \fIargtypeN\fP \fIparmN\fP)
 | |
| \fItype\fP va_arg(va_list \fIap\fP, \fItype\fP)
 | |
| void va_end(va_list \fIap\fP)
 | |
| .ft R
 | |
| .fi
 | |
| .SH DESCRIPTION
 | |
| This set of macros provides a means of writing portable procedures that
 | |
| accept variable argument lists.
 | |
| Routines having variable argument lists (such as
 | |
| .BR printf (3))
 | |
| that do not use
 | |
| .B stdarg
 | |
| are inherently nonportable, since different
 | |
| machines use different argument passing conventions.
 | |
| .PP
 | |
| A function that accepts a variable argument list is declared with "..." at
 | |
| the end of its parameter list.  It must have at least one normal argument
 | |
| before the "...".  For example:
 | |
| .PP
 | |
| .RS
 | |
| .nf
 | |
| int printf(const char *format, ...) { /* code */ }
 | |
| int fprintf(FILE *stream, const char *format, ...) { /* code */ }
 | |
| .fi
 | |
| .RE
 | |
| .PP
 | |
| .B va_list
 | |
| is a type which is used for the variable
 | |
| .I ap
 | |
| within the body of a variable argument function which is used to traverse
 | |
| the list.
 | |
| .PP
 | |
| .B va_start\c
 | |
| .RI ( ap ,
 | |
| .IR parmN )
 | |
| is called to initialize
 | |
| .I ap
 | |
| to the beginning of the list.  The last true parameter of the function,
 | |
| .IR parmN ,
 | |
| must be supplied to allow
 | |
| .B va_start
 | |
| to compute the address of the first variable parameter.
 | |
| .PP
 | |
| .B va_arg\c
 | |
| .RI ( ap ,
 | |
| .IR type )
 | |
| will return the next argument in the list pointed to by
 | |
| .IR ap .
 | |
| .I Type
 | |
| is the type to which the expected argument will be converted
 | |
| when passed as an argument.
 | |
| .PP
 | |
| Different types can be mixed, but it is up
 | |
| to the routine to know what type of argument is
 | |
| expected, since it cannot be determined at runtime.
 | |
| .PP
 | |
| .B va_end\c
 | |
| .RI ( ap )
 | |
| must be used to finish up.
 | |
| .PP
 | |
| Multiple traversals, each bracketed by
 | |
| .B va_start
 | |
| \&...
 | |
| .B va_end,
 | |
| are possible.
 | |
| .SH EXAMPLE
 | |
| .nf
 | |
| .ta +4n +4n +4n +4n
 | |
| 	\fB#include\fP <stdarg.h>
 | |
| .sp 0.4
 | |
| 	execl(\fBconst char\fP *path, \fB...\fP)
 | |
| 	{
 | |
| 		\fBva_list\fP ap;
 | |
| 		\fBchar\fP *args[100];
 | |
| 		\fBint\fP argno = 0;
 | |
| 
 | |
| 		\fBva_start\fP(ap, path);
 | |
| 		\fBwhile\fP ((args[argno++] = \fBva_arg\fP(ap, \fBchar\fP *)) != NULL) {}
 | |
| 		\fBva_end\fP(ap);
 | |
| 		\fBreturn\fP execv(path, args);
 | |
| 	}
 | |
| .DT
 | |
| .fi
 | |
| .SH NOTES
 | |
| It is up to the calling routine to determine how many arguments
 | |
| there are, since it is not possible to determine this from the
 | |
| stack frame.  For example,
 | |
| .B execl
 | |
| passes a null pointer to signal the end of the list.
 | |
| .B Printf
 | |
| can tell how many arguments are supposed to be there by the format.
 | |
| .PP
 | |
| The macros
 | |
| .B va_start
 | |
| and
 | |
| .B va_end
 | |
| may be arbitrarily complex;
 | |
| for example,
 | |
| .B va_start
 | |
| might contain an opening brace,
 | |
| which is closed by a matching brace in
 | |
| .BR va_end .
 | |
| Thus, they should only be used where they could
 | |
| be placed within a single complex statement.
 | |
| .SH BUGS
 | |
| It is impossible to properly show the macros as C declarations as is
 | |
| done in the synopsis.  They can never be coded as C functions, because
 | |
| all three macros use their arguments by address, and the
 | |
| .I type
 | |
| field is certainly impossible.
 | |
| Just look at them as being part of the C language, like
 | |
| .BR sizeof .
 | 
