One question: why are you passing a pointer to the va_list? You can just pass the va_list itself, vsnprintf does that for example. And since vsnprintf does it, I think it's safe and legal use of va_list.