Other Languages - C programming - Asked By Swapneel on 10-Aug-11 11:41 AM

what does va_arg macro does in stdarg library.
I have read the help section provided with the compiler but was not able to understand what it
was telling.

can anyone explain me.
I am using these for "Function with variable number of arguments".


regards
Swapneel
Riley K replied to Swapneel on 10-Aug-11 12:45 PM
Variadic macros are function-like macros that contain a variable number of arguments

To use variadic macros, the ellipsis may be specified as the final formal argument in a macro definition, and the replacement identifier__VA_ARGS__ may be used in the definition to insert the extra arguments. __VA_ARGS__ is replaced by all of the arguments that match the ellipsis, including commas between them.


A macro can be declared to accept a variable number of arguments much as a function can. The syntax for defining the macro is similar to that of a function

Here is an example:

     
#define eprintf(...) fprintf (stderr, __VA_ARGS__)

This kind of macro is called variadic. When the macro is invoked, all the tokens in its argument list after the last named argument (this macro has none), including any commas, become the variable argument. This sequence of tokens replaces the identifier__VA_ARGS__ in the macro body wherever it appears. Thus, we have this expansion:

     eprintf ("%s:%d: ", input_file, lineno)
          ==>  fprintf (stderr, "%s:%d: ", input_file, lineno)
  check these links also
http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
http://aelinik.free.fr/c/ch15.htm

Devil Scorpio replied to Swapneel on 10-Aug-11 03:39 PM
Hi Swapneel,

va_arg macro is used to retrieve next argument

This macro expands to an expression that has the type type and the value of the next argument in the variable arguments list.

The next call to this macro will expand to the following argument in the same order as passed to the function.

Notice that va_arg cannot determine the actual type of the argument passed to the function, but uses whatever type is passed as the type macro argument as its type.

Notice also that va_arg does not determine either whether the retrieved argument is the last argument passed to the function (or even if it is an element past the end of that list). The function should be designed in such a way that the amount of parameters can be inferred in some way by the values of either the named parameters or the additional arguments already read.

Declaration
type va_arg ( va_list ap, type )

Parameters
ap
Object of type va_list with information about the additional arguments an their retrieval state. This object shall have been initialized by an initial call to va_start before the first call to va_arg.
type
A type name. This type name is used as the type of the expression this macro expands to (i.e., its return type).
For a type expression to be suitable for its use with va_arg it must be such that when an asterisk (*) would be appended to its right the resulting expression would be a valid pointer type to a type object.

Return Value
Returns the next additional argument as an expression of type type.

Example

/* va_arg example */
#include <stdio.h>
#include <stdarg.h>

int FindMax ( int amount, ...)
{
  int i,val,greater;
  va_list vl;
  va_start(vl,amount);
  greater=va_arg(vl,int);
  for (i=1;i<amount;i++)
  {
    val=va_arg(vl,int);
    greater=(greater>val)?greater:val;
  }
  va_end(vl);
  return greater;
}

int main ()
{
  int m;
  m= FindMax (7,702,422,631,834,892,104,772);
  printf ("The greatest one is: %d\n",m);
  return 0;
}


This FindMax function takes as its first parameter the amount of additional arguments it is going to get. The first additional argument is retrieved and used as an initial reference for comparison, and then the remaining additional arguments are retrieved in a loop and compared to return the greatest one (which in this case is 892).