Are there targets where `va_end` does anything non-trivial?
Asked Answered
B

2

9

All versions of varargs.h and/or stdarg.h I've seen either define va_end as an empty macro or some opaque compiler-specific function that I guess doesn't do anything either. The rationale in the C standard states "some implementations might need it", but gives no more details.

When would there be a real need for a va_end()? Any examples of ABI that would require such, preferably with an explanation?

Bikales answered 10/8, 2021 at 16:25 Comment(5)
The question was closed as a near-duplicate on when va_end should be called. Not my question (I know it should be called always--just in case it does something non-trivial). I'm curious what ABI would require a non-trivial va_end.Bikales
The third answer in the duplicate explains an ABI that might require a non-empty implementation of va_end. The ABI doesn't actually specify how varargs are implemented. So the answer would be some implementation that stores the args not on the stackMaterialist
@AjayBrahmakshatriya: Which is the "third answer"? People can sort them differently. But anyway, none of those answers actually do so, as far as I can tell. greyfade vaguely says mixed stack/register ABIs "may be more complicated" but doesn't explain where va_end would be needed. Maxim explains why x86-64 SysV needs va_copy but not va_end. James Curran just says "on platforms which have less traditional schemes, it becomes necessary" without elaborating which platforms or why. I am voting to reopen this.Buggy
I could imagine a "user space" implementation which doesn't have special compiler support, and that needs some variable amount of scratch space, but doesn't have access to VLAs or alloca. It might be forced to get it from malloc, and then va_end() could do the free().Buggy
Now that this is no longer a dupicate... where's the "original" question?Poach
R
7

Older versions of Fabrice Bellard's tcc implemented va_start() using malloc() and va_end() using free(): so failing to call va_end() would leak memory. See here. This is because it made va_list a pointer to a structure, and malloc()/free() (or technically compiler builtins for them) were used to allocate/free the structure. In newer versions of tcc, va_list is now a single-element array of a structure instead of a pointer, and hence va_end() is now effectively a no-op, like it normally is.

Roney answered 1/8, 2023 at 13:34 Comment(1)
THat was insane implemetation :)Blakeblakelee
P
-2

C has been around for a long, long time and has many standards. These standards tend to give compilers some leeway, letting them implement their own padding/headers/etc. for performance and other reasons. I assume this was added because, as mentioned, "some compilers might need it." Though languages try to abstract their implementation details, some things - inevitably - slip through the cracks... Hope this was helpful =]

Pontus answered 21/1, 2022 at 19:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.