I am reading a stdarg.h (link below) header file which defines the va_arg macro as follows
/*
* Increment ap to the next argument in the list while returing a
* pointer to what ap pointed to first, which is of type t.
*
* We cast to void* and then to t* because this avoids a warning about
* increasing the alignment requirement.
*/
#define va_arg(ap, t) \
(((ap) = (ap) + __va_argsiz(t)), \
*((t*) (void*) ((ap) - __va_argsiz(t))))
The line
((ap) = (ap) + __va_argsiz(t))
reassigns the value of ap however I don't understand the purpose of the comma or the line
*((t*) (void*) ((ap) - __va_argsiz(t)))
We need to return to the caller what ap
has been pointed to, and advance ap
. An equivalent would be
old_ap = ap
ap = ap + argsiz
return *old_ap
However, that would require an extra variable, which is very hard (if possible) deal with in a macro in a portable way. Instead, the macro relies on a comma expression. It advances ap
, and then computes its old value, which becomes a value of the comma expression, that is of the entire macro.