I've read about variable arguments functions "int func(int, ...)
".
Where do the arguments of these functions get allocated (stack or heap)?
Because I read that the va_end()
macro frees space assigned to va_list
, so that word "frees" caught my eyes.
Note: I know that regular functions go to stack, but this type of function is interesting as the number of arguments is not known.
I just want to know for sure that it's not like arrays with no pre-defined space;
we use malloc()
and free()
at the end.
Link: https://www.tutorialspoint.com/cprogramming/c_variable_arguments.htm
c itself doesn't specify things like "heap" or "stack", so programming standard and portable c, you should better think in categories of the c standard: static, automatic and dynamic storage.
Nevertheless, in a typical implementation, "automatic storage" translates to "the stack is used for it". This is the case for function arguments and variadic functions are no exception here.
The reason va_end()
might free some dynamic storage (typically: allocated on the heap) is that the va_arg()
macro typically needs some context information to find the next argument. va_start()
will allocate the memory for that information (not for the arguments themselves) and initialize it in a way so that the first va_arg()
call returns the first variadic argument.
Note that an implementation of va_start()
doesn't have to allocate memory. va_list
might be defined in a way that it provides the space for the required context information. But that should be of no interest at all to you as the programmer, all the va_*
stuff is a black box for you and if the documentation states "call va_end()
when done for cleanup", you just do it ;)
Generally platforms have a calling convention. The first few arguments go in registers, the subsequent ones go on the stack. That's deliberately opaque to C code itself. va_start and va_end provide a wrapper round that calling convention, to allow you to access the arguments in sequence by index rather than by name.
Note that you can't build a va_args block at runtime. That's one of the few things C does not allow you to do. You can only generate the block by calling a variable args function.
Also note that in reality variable args lists are used to wrap calls to vsprintf(). You'll almost never find them used for any other purpose in production C code.