Variable arguments in C functions

2019-09-21 04:54发布

问题:

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

回答1:

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 ;)



回答2:

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.



标签: c stack heap