LINUX TIPS AND TRICKS --- February 16, 2001

Published by ITworld.com -- changing the way you view IT
http://www.itworld.com/newsletters
________________________________________________________________________________

Variadic Functions
By Danny Kalev

C provides a special mechanism for defining functions that take a 
variable number of arguments. printf() and scanf() are typical examples 
of these variadic functions. A variadic function must take at least one 
named argument (usually, a format string), but the rest of the 
arguments are optional. A special mechanism detects the number of 
unnamed arguments and their types, as we will shortly see. A variadic 
function is declared as follows:

    void printf(const char * fmt,...);

The ellipsis indicates that the function may take any number of 
arguments after the mandatory fmt. A variadic function must use C's 
default calling convention. A function declared with the "pascal" 
calling convention, for instance, cannot take a variable argument list.

Usage
Passing a different number of arguments of different types is 
particularly useful in debugging and logging functions. Consider a 
debugging function that displays a program's variables to the screen or 
writes them to a file; such a function can be used to debug any 
application. Normally, you would use printf() for this purpose; 
however, because printf() doesn't support user-defined structs and 
unions, writing a custom version may be more useful.

Implementation
First, we declare a variadic function that takes a format string and a 
variable argument list:

    void emit(const char *fmt,...);

For the sake of brevity, the format codes shall be 'd' for double 
and 'i' for int. For example:

    int ID;
    double salary;
    /*..*/
    emit("is", ID, salary);

The standard header <stdarg.h> defines the necessary macros for 
traversing unnamed arguments. A variable of type va_list will refer to 
each argument in turn. This variable is traditionally called ap 
("argument pointer"). The second macro, va_start(), initializes ap to 
point to the first unnamed argument. va_start() takes ap and the last 
named argument of the variadic function:

    va_start(ap, fmt); /*make ap point to the first arg after fmt*/

The third macro, va_arg(), takes ap and the current argument's type-
name. It returns the argument and advances ap to the next one (we rely 
on the format string to detect the argument list's end). Finally, the 
macro va_end(ap) must be called before the function returns to perform 
the necessary cleanup. Here's the complete emit() function:

    void emit(const char *fmt,...)
    {
     va_list ap /*will point to each unnamed argument in turn*/
     int num;
     double d;
     const char *p=fmt;
     va_start(ap,fmt); /* point to first element after fmt*/
     while(*p)
     {
      if (*p=='i') /*int*/
      {
       num=va_arg(ap,int);
       printf("%d",num);
      }
      else if (*p=='d') /*double*/
      {
       d=va_arg(ap,double);
       printf("%f",d);
      }
      else 
      {
       printf("unsupported format flag");
       break;
      }
      ++p;
     }/*while*/
     va_end(ap) /*cleanup*/ 
    }
    int main()
    {
     double salary=1000.00;
     int id=1234;
     emit("di",salary, id);
    }

About the author(s)
----------------
Danny Kalev is a system analyst and software engineer with more than 10 
years of experience, specializing in C++ and object-oriented analysis 
and design on various platforms including VMS, DOS, Windows, Unix, and 
Linux. His technical interests involve code optimization, networking, 
and distributed computing. He is also a member of the ANSI C++ 
standardization committee and the author of ANSI/ISO C++ Professional 
Programmer's Handbook (Que, 1999). Contact him at linuxnl@excite.com.

________________________________________________________________________________

ADDITIONAL RESOURCES

Getting the most from your shell 
A helpful guide to command-line editing, aliases and functions, and 
shell programming

http://www.unixinsider.com/jsw/lintps_nl/swol-10-2000/
swol-1027-unixshell.html

Unix command line 101: How much do you know? 
Arguments and options on the half-shell

http://www.unixinsider.com/jsw/lintps_nl/swol-10-1999/
swol-10-unix101.html

Tips on good shell programming practices 
What #! really does

http://www.unixinsider.com/jsw/lintps_nl/swol-09-1999/
swol-09-unix101.html

________________________________________________________________________________

COMMUNITY DISCUSSIONS

Linux Software Development
Hone your Linux development skills, share your expertise, and put out 
the occasional call for help in this discussion for programmers of all 
levels. Moderated by Danny Kalev.

http://www.itworld.com/jump/lintps_nl/forums.itworld.com/
webx?14@@.ee6b652/244!skip=175

Desktop Linux
Linux is making its presence felt on the desktop, but is it stable and 
polished enough for prime time? Talk distributions, window managers, 
themes, and desktop politics here.

http://www.itworld.com/jump/lintps_nl/forums.itworld.com/
webx?14@8.CQyRao7ffDm^0@.ee6b663/410!skip=336

________________________________________________________________________________

CONTACTS

* For editorial comments, write Andrew Santosusso, Associate Editor, 
  Newsletters at: andrew_santosusso@itworld.com

* For advertising information, write Dan Chupka, Account Executive at:
  dan_chupka@itworld.com

* For recruitment advertising information, write Jamie Swartz, Eastern
  Regional Sales Manager at: jamie_swartz@itworld.com or Paul Duthie,
  Western Regional Sales Manager at: paul_duthie@itworld.com

* For all other inquiries, write Jodie Naze, Product Manager, 
  Newsletters at: jodie_naze@itworld.com

________________________________________________________________________________

PRIVACY POLICY
http://www2.itworld.com/CDA/ITW_Privacy_Policy 

Copyright 2001 ITworld.com, Inc., All Rights Reserved.

http://www.itworld.com
