0

Here is source code:

#include <stdarg.h> 
void foo(char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    int a, b, d, e;
    double c;
    a = va_arg(ap, int);
    va_end(ap);
}

And here is the code after preprocessing(ignoring #include and preprocessor comments(#)):

void foo(char *fmt, ...)
{
     va_list ap;
     __builtin_va_start(ap, fmt);
     int a, b, d, e;
     double c;
     a = __builtin_va_arg(ap, int); // int as an argument after processing!
     __builtin_va_end(ap);
}

so, how does __builtin_va_arg(ap, int) works ? When this macro expanded ?

ravivasani75
  • 113
  • 6
  • 1
    This not a macro, but a instrinsic function which will handled by the compiler. Usually what happens is that the compiler set `ap` to the element after `fmt` (last fiexed argument) on the stack with `va_start`. After that you can access those elements by `va_arg` function. – Eraklon Apr 13 '20 at 14:16
  • [va_arg](https://www.techonthenet.com/c_language/standard_library_functions/stdarg_h/va_arg.php), [implementation quesiton](https://stackoverflow.com/questions/49733154/how-is-builtin-va-list-implemented) – ryyker Apr 13 '20 at 14:34

1 Answers1

2

These are not macros. They are built-in primitives implemented by the compiler itself. (That is, the particular compiler you are using.)

The actual syntax and semantics of these built-ins is deliberately not documented. You must not use them directly in a program, as indicated by the fact that their names start with two underscores. (Only documented symbols starting with two underscores may be used in a program.) When the compiler encounters them after preprocessing, it will emit the appropriate code (which likely cannot be written in C).

rici
  • 234,347
  • 28
  • 237
  • 341