Previous Table of Contents Next


3.10.10. <stdarg.h>

The facilities (most of which are macros) in the header <stdarg.h> provide mechanisms that permit functions accepting a varying number of arguments (such as printf) to access those arguments.

The access mechanism revolves around an argument pointer, a descriptor used to manipulate the variable-length argument list. This descriptor is of the abstract type va_list. Facilities exist for initializing this descriptor, fetching arguments, and disposing of the descriptor. The calling function must know the expected type of each argument as it fetches it; there are no facilities for querying the type or number of arguments actually supplied during a particular call.

3.10.10.1. va_start

va_start(va_list argp, lastarg)

va_start initializes argp so that it can begin accessing variable arguments. lastarg is the name of the last of the function’s fixed arguments.

3.10.10.2. va_arg

va_arg(va_list argp, argtype)

va_arg fetches a value of type argtype as the next argument from the variable-length argument list accessed by argp. argtype is specified by using the same sort of type name (base type plus optional identifierless declarator) as is used in type casts and sizeof expressions. The specified type must be the type of the corresponding argument actually passed, after the default argument promotions (see section 3.5.3) have been applied; it is the function’s responsibility to know the type somehow. (printf, for example, determines the expected type of each argument by parsing the format string.)

3.10.10.3. va_end

va_end(va_list argp)

va_end indicates that the calling function is finished with variable-length argument processing. va_list must be called so that the variable-length argument machinery can reclaim any resources or otherwise clean up.

As an example of the use of the <stdarg.h> macros, here is a stripped-down implementation of printf. (It cheats and calls on sprintf to do its actual numeric formatting. See section 3.10.1.6 for a description of sprintf.)

#include <stdio.h>
#include <stdarg.h>
void miniprintf(const char *fmt, …)
{
       va_list argp;
       const char *p;
       char tmpbuf[25];
       int i;
       va_start(argp, fmt);
       for(p = fmt; *p != ‘\0’; p++)
               {
               if(*p != ‘%’)
                       {
                       putchar(*p);
                       continue;
                       }
       switch(*++p)
           {
           case ‘c’:
               i = va_arg(argp, int); putchar(i);
               break;
           case ‘d’:
               i = va_arg(argp, int);
               sprintf(tmpbuf, “%d”, i); fputs(tmpbuf, stdout);
               break;
           case ‘o’:
               i = va_arg(argp, int);
               sprintf(tmpbuf, “%o”, i);
               fputs(tmpbuf, stdout);
               break;
           case ‘s’:
               fputs(va_arg(argp, char *), stdout);
               break;
           case ‘x’:
               i = va_arg(argp, int);
               sprintf(tmpbuf, “%x”, i); fputs(tmpbuf, stdout);
               break;
           case ‘%’:
               putchar(‘%’);
               break;
          }
       }
   va_end(argp);
}

For another example, see section 3.10.1.7.

3.10.11. <stddef.h>

The header <stddef.h> defines several types and macros. The types have definitions that vary from compiler to compiler but, if used with care, can result in more portable programs.

NULL A macro expanding to a null pointer constant (generally 0 or (void *)0).
size_t An unsigned integral type used for representing the sizes of objects (as computed by sizeof and functions such as strlen, and passed to functions such as malloc, strncat, and fwrite).
ptrdiff_t A signed integral type that is the result of pointer subtraction.
wchar_t A wide character type that may have more range than plain char, used for holding values in extended or multinational character sets. See also section 3.10.17.
offsetof() A macro that computes the byte offset of a member in a structure, as in offsetof(struct tm, tm_year).

3.10.12. <assert.h>

<assert.h> defines one macro, assert, which is used to document (and test) runtime assertions.

void assert(int e)

The value e is any expression that the programmer asserts will be true as long as the program is functioning correctly. Should the expression ever evaluate as false, it is assumed to represent a serious programming error, and the program is aborted with a message indicating that the assertion failed.

Assertions should be used to detect “can’t happen” situations during software development, not to detect expected error conditions such as end-of-file, file not found, out of memory, and so on.

If the macro NDEBUG is defined (with any value) when <assert.h> is included, assertions are suppressed. (This macro might be defined when building a production version of a program, for example, if it were felt that the “can’t happen” conditions in that version truly couldn’t happen.)

3.10.13. <errno.h>

<errno.h> declares the global errno in which is stored a code representing the specific reason for failure of certain library functions. (errno is set to a meaningful value only when certain library functions fail; the value is generally not meaningful otherwise.) errno can be thought of as a global variable, but it may be a macro with a clever expansion that allows distinct per-thread error codes in a threaded environment. Also defined in <errno.h> are symbolic constants for the error codes. The only error codes specified in the C standard are EDOM and ERANGE, indicating domain and range errors, respectively, for the functions in <math.h>. Most implementations define several additional error values.


Previous Table of Contents Next