Stdarg.h
Encyclopedia
stdarg.h is a header in the C standard library
C standard library
The C Standard Library is the standard library for the programming language C, as specified in the ANSI C standard.. It was developed at the same time as the C POSIX library, which is basically a superset of it...

 of the C programming language that allows functions to accept an indefinite number of arguments. It provides facilities for stepping through a list of function arguments of unknown number and type. C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...

 provides this functionality in the header cstdarg; the C header, though permitted, is deprecated in C++.

The contents of stdarg.h are typically used in variadic function
Variadic function
In computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages....

s, though they may be used in other functions (for example, vprintf) called by variadic functions.

Declaring variadic functions

Variadic functions are functions which may take a variable number of arguments and are declared with an ellipsis
Ellipsis
Ellipsis is a series of marks that usually indicate an intentional omission of a word, sentence or whole section from the original text being quoted. An ellipsis can also be used to indicate an unfinished thought or, at the end of a sentence, a trailing off into silence...

 in place of the last parameter. An example of such a function is printf
Printf
Printf format string refers to a control parameter used by a class of functions typically associated with some types of programming languages. The format string specifies a method for rendering an arbitrary number of varied data type parameter into a string...

. A typical declaration is


int check(int a, double b, ...);


Variadic functions must have at least one named parameter, so, for instance,


char *wrong(...);


is not allowed in C. (In C++, such a declaration is permitted, but not very useful.) In C, a comma must precede the ellipsis; in C++, it is optional.

Defining variadic functions

The same syntax is used in a definition:


long func(char, double, int, ...);

long func(char a, double b, int c, ...)
{
/* ... */
}


An ellipsis may also appear in old-style function definitions:


long func;

long func(a, b, c, ...)
char a;
double b;
{
/* ... */
}

stdarg.h types

Name Description Compatibility
va_list type for iterating arguments C89

stdarg.h macros

Name Description compatibility
va_start Start iterating arguments with a va_list C89
va_arg Retrieve an argument C89
va_end Free a va_list C89
va_copy Copy contents of one va_list to another C99
C99
C99 is a modern dialect of the C programming language. It extends the previous version with new linguistic and library features, and helps implementations make better use of available computer hardware and compiler technology.-History:...


Accessing the arguments

To access the unnamed arguments, one must declare a variable of type va_list in the variadic function. The macro va_start is then called with two arguments: the first is the variable declared of the type va_list, the second is the name of the last named parameter of the function. After this, each invocation of the va_arg macro yields the next argument. The first argument to va_arg is the va_list and the second is the type of the next argument passed to the function. Finally, the va_end macro must be called on the va_list before the function returns. (It is not required to read in all the arguments.)

C99
C99
C99 is a modern dialect of the C programming language. It extends the previous version with new linguistic and library features, and helps implementations make better use of available computer hardware and compiler technology.-History:...

 provides an additional macro, va_copy, which can duplicate the state of a va_list. The macro invocation va_copy(va2, va1) copies va1 into va2.

There is no mechanism defined for determining the number or types of the unnamed arguments passed to the function. The function is simply required to know or determine this somehow, the means of which vary. Common conventions include:
  • Use of a printf
    Printf
    Printf format string refers to a control parameter used by a class of functions typically associated with some types of programming languages. The format string specifies a method for rendering an arbitrary number of varied data type parameter into a string...

    or scanf
    Scanf
    Scanf format string refers to a control parameter used by a class of functions typically associated with some types of programming languages. The format string specifies a method for reading a string into an arbitrary number of varied data type parameter...

    -like format string with embedded specifiers that indicate argument types.
  • A sentinel value
    Sentinel value
    In computer programming, a sentinel value is a special value whose presence guarantees termination of a loop that processes structured data...

     at the end of the variadic arguments.
  • A count argument indicating the number of variadic arguments.

Type safety

Some C implementations provide C extensions that allow the compiler to check for the proper use of format strings and sentinels. Barring these extensions, the compiler usually cannot check whether the unnamed arguments passed are of the type the function expects, or convert them to the required type. Therefore, care should be taken to ensure correctness in this regard, since undefined behavior results if the types do not match. For example, if passing a null pointer, one should not write simply NULL (which may be defined as 0) but cast to the appropriate pointer type. Another consideration is the default argument promotions applied to the unnamed arguments. A float will automatically be promoted to a double. Likewise, arguments of types narrower than an int will be promoted to int or unsigned int. The function receiving the unnamed arguments must expect the promoted type.

GCC
GNU Compiler Collection
The GNU Compiler Collection is a compiler system produced by the GNU Project supporting various programming languages. GCC is a key component of the GNU toolchain...

 has an extension that checks the passed arguments:

Example

  1. include
  2. include


/* print all non-negative args one at a time;
all args are assumed to be of int type */
void printargs(int arg1, ...)
{
va_list ap;
int i;

va_start(ap, arg1);
for (i = arg1; i >= 0; i = va_arg(ap, int))
printf("%d ", i);
va_end(ap);
putchar('\n');
}

int main(void)
{
printargs(5, 2, 14, 84, 97, 15, 24, 48, -1);
printargs(84, 51, -1);
printargs(-1);
printargs(1, -1);
return 0;
}


This program yields the output:


5 2 14 84 97 15 24 48
84 51

1


To call other var args functions from within your function (such as sprintf) you need to use the var arg version of the function (vsprintf in this example):

void MyPrintf(const char* format, ...)
{
va_list args;
char buffer[BUFSIZ];

va_start(args,format);
vsprintf (buffer, format, args );
FlushFunnyStream(buffer);
va_end(args);
}

varargs.h

POSIX
POSIX
POSIX , an acronym for "Portable Operating System Interface", is a family of standards specified by the IEEE for maintaining compatibility between operating systems...

 defines the legacy header varargs.h, which dates from before the standardization of C and provides functionality similar to stdarg.h. This header is not part of ISO C. The file, as defined in the second version of the Single UNIX Specification
Single UNIX Specification
The Single UNIX Specification is the collective name of a family of standards for computer operating systems to qualify for the name "Unix"...

, simply contains all of the functionality of C89 stdarg.h, with the exceptions that: it cannot be used in standard C new-style definitions; you may choose not to have a given argument (standard C requires at least one argument); and the way it works is different—in standard C, one would write:

  1. include


int summate(int n, ...)
{
va_list ap;
int i = 0;

va_start(ap, n);
for
i += va_arg(ap, int);
va_end(ap);
return i;
}


or with old-style function definitions:

  1. include


int summate(n, ...)
int n;
{
/* ... */
}


and call with


summate(0);
summate(1, 2);
summate(4, 9, 2, 3, 2);


With varargs.h, the function would be:

  1. include


summate(n, va_alist)
va_dcl /* no semicolon here! */
{
va_list ap;
int i = 0;

va_start(ap);
for
i += va_arg(ap, int);
va_end(ap);
return i;
}


and is called the same way.

varargs.h requires old-style function definitions because of the way the implementation works.
The source of this article is wikipedia, the free encyclopedia.  The text of this article is licensed under the GFDL.
 
x
OK