va_end
se utiliza para hacer la limpieza. No quieres destrozar la pila, ¿verdad?
De man va_start
:
va_end()
Cada invocación de va_start() debe ser emparejado por una invocación correspondiente de va_end() en la misma función. Después de la llamada va_end (ap), la variable ap no está definida. Se pueden realizar múltiples recorridos de la lista, cada uno entre corchetes con va_start() y va_end(). va_end() puede ser una macro o una función.
Tenga en cuenta la presencia de la palabra debe.
La pila podría dañarse porque no sabe qué va_start()
está haciendo. Las macros va_*
están destinadas a ser tratadas como cuadros negros. Cada compilador en cada plataforma puede hacer lo que quiera allí. Puede no hacer nada, o puede hacer mucho.
Algunos ABI pasan las primeras args en los registros, y el resto en la pila. A va_arg()
puede ser más complicado. Puede buscar cómo una implementación determinada hace varargs, lo que puede ser interesante, pero al escribir un código portátil debe tratarlos como operaciones opacas.
Es una muy buena pregunta. Me gustaría que alguien lo respondiera describiendo una arquitectura donde va_end no es una opción negativa. – erikkallen
FYI: MSVS2008 - #define _crt_va_end (ap) (ap = (va_list) 0) – Yarik
@erikkallen: Haga una búsqueda en google de "define va_end" y encontrará algunas definiciones inusuales que pueden o no ser esencialmente un no- op. – PlasmaHH