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)))
Link to stdarg.h file
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.
There is an expression with the comma operator.
The first sub-expression
(((ap) = (ap) + __va_argsiz(t))
increase the pointer ap
.
The second sub-expression
*((t*) (void*) ((ap) - __va_argsiz(t))))
returns the value pointed to by the pointer ap
before its increment.
If you have a question relative to the comma operator then it allows to combine several full expressions in one expression.
Consider for example the following program
#include <stdio.h>
int main(void)
{
int a[] = { 1, 2 };
size_t i = 0;
printf( "%d\n", ( i++, a[i] ) );
return 0;
}
Its output is
2
Here the argument of the printf
call is an expression with the comma operator.
Or a more interesting example
#include <stdio.h>
int main(void)
{
int a[] = { 1, 2 };
size_t i = 0;
printf( "%d\n", a[i] ), i++, printf( "%d\n", a[i] );
return 0;
}
The program output is
1
2
Here the expression statement
printf( "%d\n", a[i] ), i++, printf( "%d\n", a[i] );
contains an expression with using two comma operators.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With