可变长度参数列表错误

时间:2018-06-28 15:22:01

标签: c variadic-functions

很多年前,我编写了一个自定义打印函数,声明如下:

void my_printf(char *format_string, ... )
{
    // too complex to list here
}

我可以这样称呼它:

my_printf("Number of apples = %d\n",apple);

此功能始终运行良好。我现在希望创建一个包装函数,使其像这样在开始时需要一个额外的整数:

void my_printf_extra(int extra,char *format_string, ...

可以这样称呼:

my_printf_extra(debug_level,"Number of apples = %d\n",apple);

并且我希望包装函数以这种方式调用原始文件:

void my_printf_extra(int extra,char *format_string, ... )
{
    if (extra == some_test)
    {
        my_printf(** not quite sure what goes here **);
    }
}

我的猜测是:

void my_printf_extra(int extra,char *format_string, ... )
{
    va_list vptr;

    if (extra == some_test)
    {
        va_start(vptr,format_string);
        my_printf(format_string,vptr);
        va_end(vptr);
    }
}

但是它不起作用。在我的最终输出中,我看到

Number of apples = -46467968

或某些此类垃圾编号(当真实值为1时)。用字符串调用my_printf_extra时,我看到类似的垃圾。我怀疑我对va_list的处理是错误的,但是我无法理解到底是怎么做到的。

编辑:my_printf()超级灵活,可以打印到各种不同的地方。有时,它只是将文本附加到丰富的编辑控制窗口中。这一切都取决于各种标志以及所打印内容的内容。

1 个答案:

答案 0 :(得分:4)

由于my_printf不希望有va_list,因此您不能将其传递给它。

在这种情况下,使用宏是有意义的:

#define my_printf_extra(extra, format_string, ... ) \
do {\
    if ((extra) == some_test)\
    {\
        my_printf((format_string), __VA_ARGS__);\
    }\
} while (0)

__VA_ARGS__宏替换所有其他参数。请注意,这需要支持C99的编译器。

或者,您可以修改my_printf以添加额外的逻辑,将名称更改为内部名称,然后将my_printfmy_printf_extra定义为调用内部函数的宏:

void my_printf_impl(int extra, char *format_string, ... )
{
    if (extra != some_test) {
        return;
    }

    ...
}

#define EXTRA_DEFAULT 0
#define my_printf(format_string, ...) \
    my_printf_impl(EXTRA_DEFAULT, format_string, __VA_ARGS__)
#define my_printf_extra(extra, format_string, ...) \
    my_printf_impl(extra, format_string, __VA_ARGS__)