The vsnprintf function is the same as the snprintf function, but
    instead of being called with a variable number of arguments, it
    is called with an argument list that has been initialized by va_
    start (and possibly with subsequent va_arg calls).
    This function does not invoke the va_end macro. Because the
    function invokes the va_arg macro, the value of ap after the
    return is unspecified.
    Applications using vsnprintf should call va_end(ap) afterwards to
    clean up.