My code contains snippets like these:
std::va_list ap; va_start(ap, msgfmt); snprintf_buf buf; const tchar * msg = buf.print_va_list(msgfmt, ap);
Unfortunately, no. The specification of va_start and va_end requires that:
va_start
va_end
Each invocation of the va_start and va_copy macros shall be matched by a corresponding invocation of the va_end macro in the same function.
va_copy
Therefore, va_end must be in the variadic function itself, not a class destructor.