未定义的行为-C++为什么va_start期望最后一个非可变函数参数



我正在使用Visual Studio 2012编译以下示例代码:

#include <stdarg.h>
#include <stdio.h>
const char * __cdecl foo(const char * format, const char * requiredArgument, ...)
{
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
    return requiredArgument;
}
int main(int, char **)
{
    foo("The %s is %d pixels wide and %d pixels high.", "box", 300, 200);
    return 0;
}

程序的调试构建在打印消息"框宽300像素,高200像素"后正常终止。

发布版本因分段错误而崩溃。

我对这种行为的解释——但我可能错了,如果是,请纠正我——是我错误地指定了一个函数参数,而不是va_start中的最后一个非变元参数,这里唯一允许的形式是va_start(args, requiredArgument),而不是我希望的va_start(args, format)。换言之,我滥用va_start的方式使整个程序流程变得不可预测,因此分割错误在这里很好。

如果我的假设是正确的,我现在有两个问题:

  • 如果选择其他内容显然是非法的,为什么还要在va_start中指定最后一个正式声明的函数参数?

  • 为什么挑剔的VC++编译器没有对这样一个易于检测和潜在的关键陷阱发出警告?

如果选择其他任何东西显然是非法的,为什么还要在va_start中指定最后一个正式声明的函数参数?

因为该宏需要知道最后一个参数的地址

为什么挑剔的VC++编译器没有对这样一个易于检测和潜在的关键陷阱发出警告?

因为它不够"聪明"。或者其创建者决定不包含此警告。或者它可以,但默认情况下它是关闭的,您可以使用一些编译器标志来打开它。

相关内容

  • 没有找到相关文章

最新更新