C ++为什么va_start期望最后一个非变量函数参数?

时间:2013-02-03 15:26:01

标签: c undefined-behavior variadic-functions

我正在使用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像素”后正常终止。

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

我对这种行为的解释 - 但我可能错了,请纠正我,如果是这样 - 是我错误地指定了一个函数参数而不是{}中的最后一个非变量函数参数{1}},唯一可以接受的格式是va_start,而不是va_start(args, requiredArgument),就像我希望的那样。 换句话说,我误用了va_start(args, format),使得整个程序流程变得不可预测,因此分段错误在这里就好了。

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

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

  • 为什么那些挑剔的VC ++编译器不会对如此易于检测和潜在的关键陷阱发出警告?

1 个答案:

答案 0 :(得分:2)

  

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

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

  

为什么那些挑剔的VC ++编译器不会对如此易于检测和潜在的关键陷阱发出警告?

因为它不够“智能”。或者它的创建者决定不包括这个警告。或许可以,但默认情况下它已关闭,你可以使用一些编译器标志打开它。