首页 > 未分类 > vxxxxf 系列函数会修改 args

vxxxxf 系列函数会修改 args

之前碰到过一次,结果 de 完 bug 转头就忘了。
于是今天就又花了半天来 de 这个 bug。

vxxxxf 包括 vsnprintf 等等等等。

C99 / C++11 有一个新的宏 va_copy,可以制造一个 args 的副本,然后每次调用 vxxxxf 之前传副本进去就好。
ref: http://en.cppreference.com/w/cpp/utility/variadic/va_copy

一个例子(把 vsnprintf 通过返回值返回错误改成了通过异常指示错误):

size_t string_printf(
    char *buffer,
    size_t buffer_size,
    const char *format,
    va_list args
    )
{
    
    //
    // args 第一次用于 vsnprintf 计算所需要的字符数,由于 vsnprintf
    // 可能会修改 args(实际上确实修改了),所以要搞一个副本给第一次
    // 的 vsnprintf 做参数。
    //

    va_list args_copy;

    va_copy(args_copy, args);

    BOOST_SCOPE_EXIT(&args_copy)
    {
        va_end(args_copy);
    }
    BOOST_SCOPE_EXIT_END;

    int cch_needed = vsnprintf(nullptr, 0, format, args_copy);

    if (cch_needed < 0)
    {
        throw std::runtime_error("vsnprintf failed.");
    }
    else if (static_cast<size_t>(cch_needed) > buffer_size - 1)
    {
        throw std::overflow_error("Buffer is too small.");
    }

    cch_needed = vsnprintf(buffer, buffer_size, format, args);

    if (cch_needed < 0 || static_cast<size_t>(cch_needed) > buffer_size - 1)
    {
        throw std::runtime_error("Unexpected exception.");
    }

    return cch_needed;
}

  1. li01452
    2014年7月16日20:06 | #1

    好久不见

  2. NewbieCoder
    2014年9月8日21:22 | #2

    @li01452
    好久不见